Przekazanie dodatkowego props (arrray of objects) do komponentu i wyszukanie po odpowiednim polu

0

Hej,

na wejściu pobieram dane

const erpTransactions = reactive([]);
const erpTransactionsPrevious = reactive([]);

const getTransactions = (parameters: object, object: object): void => {
  ApiService.postRequest("url", parameters)
    .then(({ data }) => {
      Object.assign(object, data);
    })
    .catch(({ response }) => {
      console.log("API Request went wrong.");
    });
};

przekazuję do komponentu w pętli

<div v-for="item in erpTransactions" :key="item.id">
  <Statistic
    :data="item"
    :previous-data="erpTransactionsPrevious"
  />
</div>

i wyświetlam w child komponent

<div> {{ data.net }} </div>

teraz potrzebuję dołożyć te same dane tylko dotyczące innego okresu ( previous-data ). W rodzicu wywołałem ten sam call do backendu tylko z innymi datami i przekazałem cały array przez props previous-data
Teraz chciałbym wyświetlić odpowiednie dane obok np.

<div> {{ data.net }} {{ previousData.net }}</div>

zacząłem tak, wrzuciłem to na widok ... dobrze znajduje odpowiedni obiekt, ale ja potrzebuję jego odpowiednie property ... bez sensu taki kod wrzucać w html

{{
  previousData.filter((obj) => {
    return obj.id === data.id;
  })
}}

jak to zrobić?

albo jak zrobić aby dwa requesty na ten sam endpoint ale z innym zakresem dat wrzucić do jednego obiektu w stylu

[
  current: [
    {id: 1, userName: Kowalski, net: 123, quantity: 567},
    {id: 2, userName: Nowak, net: 123, quantity: 567},
  ],
  previous: [
      {id: 1, userName: Kowalski, net: 111, quantity: 555},
      ...
  ]
]
0

pokonałem problem ale pojawił się następny i wydaje mi się, że jest to związane z tym, że wyświetlam child component w pętli i za każdym razem oprócz wyświetlania jednego propsa, filtruję drugiego i też chce to wyświetlić. stworzyłem funkcję, która szuka w previousData po salesRepresentativeId wziętego z data
Doczytałem w dokumentacji, pomogło typowanie propsów.

import { defineComponent, reactive, PropType } from "vue";

interface Option {
  salesRepresentativeId: number;
  salesRepresentativeName: string;
  quantity: number;
  net: number;
  paymentLeft: number;
}

interface Options extends Array<Option> {}

export default defineComponent({
  name: "sale-representative-stats",
  props: {
    data: {
      type: Object,
      required: true,
    },
    previousData: {
      type: Array as PropType<Options>,
      required: true,
    },
  },
  setup(props) {
    const prevData: object[] = reactive([]);

    const findPreviousDataById = () => {
      const filtered = props.previousData.filter((obj) => {
        return obj.salesRepresentativeId === props.data.salesRepresentativeId;
      });
      console.log(filtered);
      prevData.push(filtered);
    };

    onMounted(() => {
      findPreviousDataById();
    });

    return {
      prevData,
      findPreviousDataById,
    };
  },
});

ten console.log(filtered) daje mi poprawne dane ... odświeżam F5 pusta tablica mi pustą tablicę. może jakoś opóźnić renderowanie childa?

0

pokonałem całość i wychodzi na to, że VUE ma problem z robieniem paru rzeczy na raz ... za nas :) i delegowaniem tego w dół.
zrefaktorowałem rodzica aby metoda getTransactions() zwracała Promise

    const getTransactions = (
      parameters: object,
      object: object
    ): Promise<void> => {
      return ApiService.postRequest("api/endpoint", parameters)
        .then(({ data }) => {
          Object.assign(object, data);
        })
        .catch(({ response }) => {
          console.log("API Request went wrong.");
        });
    };

dalej w hooku onMounted użyłem Promise.all i ustawiając loaded na true gdy wszystko się wykona.

onMounted(() => {
      Promise.all([
        getTransactions(paramsCurrentPeriod, erpTransactions),
        getTransactions(paramsPreviousPeriod, erpTransactionsPrevious),
      ])
        .then(() => (loaded.value = true))

i dopiero wtedy jadę z childem

    <div
      class="col-md-12"
      v-for="item in erpTransactions"
      :key="item.salesRepresentativeId"
    >
      <SaleRepresentativeStats
        v-if="loaded"
        :data="item"
        :previous-data="erpTransactionsPrevious"
      />
    </div>

w child uprościłem wyszukiwanie poprzednich danych zwracaać obiekt zamiast tablicy obiektów ( użyłem też interfejsów)

export interface TransactionCumalativeSalesRepresentative {
  salesRepresentativeId?: number;
  salesRepresentativeName?: string;
  quantity?: number;
  net?: number;
  paymentLeft?: number;
}

const prevData: TransactionCumalativeSalesRepresentative = reactive({});

    const findPreviousData = () => {
      const filtered = props.previousData.filter((obj) => {
        return obj.salesRepresentativeId === props.data.salesRepresentativeId;
      });
      Object.assign(prevData, filtered[0]);
    };

i teraz wszystko działa

p.s. doczytałem też, że w takich przypadkach można by użyć <Suspense> ale z drugiej strony w docs jest
<Suspense> is an experimental feature. It is not guaranteed to reach stable status and the API may change before it does.

1 użytkowników online, w tym zalogowanych: 0, gości: 1