myrdstom
myrdstom

Reputation: 306

Returning results in their order from multiple api queries

I want to make multiple API calls from an array of values. I would like to resolve the first call, then the second, third, and so on in the order in which the API request receives the data. everything I've tried gets me to the point of logging the final data in the console or resolving the data but not necessarily returning the array of data in the format with which the requests were made. Below is one of the solutions I was recently playing with. It definitely does not work (and there are a lot of issues with it) but I do see the unresolved data in the console. The console.logs just show the points where some sort of accurate data is returned as an unresolved promise

Function

const sendTrackingData =  (storeKey, deliveries) => {
    const trackingUrl = deliveries.map(async (delivery) => {
        const urlData = []

        delivery.parcels.map(async (parcel) => {
            const {trackingData} = parcel;
            const carrier = trackingData.carrier.toLowerCase();
            const trackingCode = trackingData.trackingId;
            urlData.push(await getTrackingUrl(storeKey, carrier, trackingCode))
        })
        console.log(urlData)
        return urlData
    })
    return Promise.all(trackingUrl)
};

It is called here for now in a use effect

    const test = await sendTrackingData(storeKey, deliveries)
    console.log(test,'the test url data =========>')

API call

export const getTrackingUrl =  (storeKey, carrier, trackingCode) => {
    return axios.post(`random-url-address/returnedData`, {
        storeKey,
        carrier,
        trackingCode,
    });
};


Upvotes: 0

Views: 689

Answers (2)

عمر - OMAR
عمر - OMAR

Reputation: 40

you can try

delivery.parcels.map(async (parcel , index) => {
            const {trackingData} = parcel;
            const carrier = trackingData.carrier.toLowerCase();
            const trackingCode = trackingData.trackingId;
            
            urlData.splice(index, 0, await getTrackingUrl(storeKey, carrier, trackingCode));
        })
        console.log(urlData)
        return urlData

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371049

You need to call Promise.all on the main asynchronous requests - the getTrackingUrl - for the order to be preserved:

const sendTrackingData = (storeKey, deliveries) => (
    Promise.all(deliveries.map((delivery) => (
        Promise.all(delivery.parcels.map((parcel) => {
            const { trackingData } = parcel;
            const carrier = trackingData.carrier.toLowerCase();
            const trackingCode = trackingData.trackingId;
            return getTrackingUrl(storeKey, carrier, trackingCode);
        }))
    )))
);

When you want to preserve order, .push after an asynchronous request is almost never the right approach.

Upvotes: 1

Related Questions