I am new to typescript and I am working on a project where I need to populate all the fields in GridModel interface by querying data. I have the below code after several attempt which works fine.
In the below code, I pick single id from ids array and then make the necessary call to get all those fields and populate GridModel interface. Below code only works for single id which I pick as first index from ids array.
import { useEffect, useMemo, useState } from 'react'
import {
useGetClientOrdersByItemQuery,
useGetClientOrdersQuery,
useGetClientOrderLineByLineIdLazyQuery,
} from '../../../../hooks/static/use-get-client-orders-by-item'
interface GridModel {
purchaseOrderId: string | undefined,
lineNumber: string | undefined,
warehouse: string | undefined,
startShipDate: string | undefined,
}
export const useViewPurchaseOrderData = (ids: string[]) => {
const [gridData, setGridData] = useState<GridModel[]>([])
const [fetchLines, { loading: linesLoading }] = useGetClientOrderLineByLineIdLazyQuery()
const { data, loading } = useGetClientOrdersByItemQuery({
variables: { itemId: Number(ids[0]) },
skip: !ids[0],
})
const poIds = (data?.getPurchaseOrdersByItem?.map((p) => p?.purchaseOrderId)
.filter((poid): poid is number => Boolean(poid)) ?? [])
const poidToLines = useMemo(() => data?.getPurchaseOrdersByItem
?.map((p) => ({ orderId: p?.purchaseOrderId, lines: p?.lineIds })), [data])
const { data: purchaseData, loading: purchaseLoading } = useGetClientOrdersQuery({
variables: { poIds, count: poIds.length, offset: 0 },
skip: !poIds.length,
})
const purchaseOrders = purchaseData?.getPurchaseOrders?.purchaseOrders
useEffect(() => {
const lineRequests = poidToLines?.flatMap((p) => p?.lines?.map((lineId) => fetchLines({
variables: {
purchaseOrderId: p?.orderId ?? 0,
purchaseOrderLineId: lineId ?? 0,
},
}).then((result) => ({
result: result.data?.getPurchaseOrderLineByLineId,
poId: p?.orderId,
})))).filter(Boolean) as Promise<any>[]
if (purchaseOrders && purchaseOrders.length && lineRequests && lineRequests.length) {
Promise.all(lineRequests).then((lines) => {
const mapped: GridModel[] = lines.map((line) => {
const order = purchaseOrders.find((po) => po?.id === line.poId.toString())
return {
purchaseOrderId: order?.id ?? undefined,
lineNumber: line?.result.lineId ?? undefined,
warehouse: order?.site?.name ?? undefined,
startShipDate: order?.expectedShipDate ?? undefined,
}
}) ?? []
setGridData(mapped)
})
}
}, [poidToLines, purchaseOrders])
return {
data: gridData,
loading: loading || purchaseLoading || linesLoading,
}
}
Problem Statement
Is there any way where I can loop around all ids in ids array either asynchronously or sequentially inside useViewPurchaseOrderData function? And for each single id, I will do exact same thing which I am already doing in above code? So idea is -
- Iterate all id from
idsarray either asynchronously or sequentially. For each id do exact above thing and then once we have data for all id return everything back.
Is this possible to do by any chance in typescript. I am from Java, C# background so having hard time figuring out on how to do this in Typescript.
useGetClientOrdersByItemQueryaccepting only a single id. The problem is less to do with typescript and more than you cannot loop hook calls in Reactjs. Can you show us the code of use-get-client-orders-by-item?npm run codegenafter adding my graphql query. @BergiuseGetClientOrdersByItemQuery()call, at least. See github.com/apollographql/apollo-feature-requests/issues/178 stackoverflow.com/q/59938677/1048572 stackoverflow.com/q/68281221/1048572 for possible approaches. The ideal solution would obviously exposing an API that accepts an array of ids.