const axios = require('axios');
const getShipmentDetails = ((nextCall) => {
const res = axios({
method: 'post',
url: nextCall,
headers:{ Authorization: "<Generated Bearer Token>"},
data:{
"filter" : {
"type" : "postDispatch",
"states" : ["SHIPPED"],
"orderDate" : {
"from" : "2022-04-01",
"to" : "2022-04-04"
}
}
}
})
if(res['data']['hasMore'] == false ){
return res['data']['shipments'].concat(getShipmentDetails(res['data']['nextPageUrl']))
}
else{return res['data']['shipments']}
});
const result = getShipmentDetails("https://api.flipkart.net/sellers/v3/shipments/filter/");
console.log(result);
I am Recursively fetching data from paginated API. I am getting multiple errors while adding await/async functions in this code. Due to delay from the API calls output is printing "Undefined". Please update this code with await/async or any suitable method so that data from all the pages is concatenated.
CodePudding user response:
Acording to the axios docs, the axios
method returns a promise, so all you have to do is add some async/await statements in the appropriate places: async
on the getShipmentDetails
function, and await
for when its called, and an await
on axios
.
const axios = require('axios');
const SHIPMENT_AXIOS_CONFIG = { // Pulled this out for readability
method: 'post',
headers: { Authorization: '<Generated Bearer Token>'},
data: {
filter: {
type: 'postDispatch',
states: ['SHIPPED'],
orderDate: {
from: '2022-04-01',
to: '2022-04-04',
}
}
}
};
const getShipmentDetails = async (nextCall) => {
const res = await axios({ // Wait for the response
...SHIPMENT_AXIOS_CONFIG,
url: nextCall,
});
const { data } = res; // destructuring to get common properties makes the code more readable
if (data.hasMore == false) { // Should this be hasMore === true?
// Wait for the additional details
const shipments = await getShipmentDetails(data.nextPageUrl);
return data.shipments.concat(shipments);
}
return data.shipments;
};
const result = await getShipmentDetails('https://api.flipkart.net/sellers/v3/shipments/filter/');
CodePudding user response:
const axios = require('axios')
const getShipmentDetails = async ((url) => {
const res = await axios({
method: 'post',
url: url,
headers: { Authorization: "<Generated Bearer Token>"},
data: {
"filter" : {
"type" : "postDispatch",
"states" : ["SHIPPED"],
"orderDate" : {
"from" : "2022-04-01",
"to" : "2022-04-04"
}
}
}
})
if (res['data']['hasMore'] == true) {
const more = await getShipmentDetails(res['data']['nextPageUrl'])
return res['data']['shipments'].concat(more);
}
else {
return res['data']['shipments']
}
})
getShipmentDetails("https://api.flipkart.net/sellers/v3/shipments/filter/")
.then(result => console.log(result))
Should do what you want. I made the assumption that you got your hasMore
conditional backwards since logically, you'd expect hasMore
to be true if there were additional pages.
A note about async/await and promises:
If you use promises you have to use promises all the way down. Javascript doesn't offer a mechanism for blocking on a promise. So if you've got async code your only options are .then
and async/await,
which is syntactic sugar for .then
. This is different from how Promises (or the equivalent) work in many other languages, including C# and Java.
Finally a few stylistic things:
Javascript conventional style always puts a space between if
and the parens around the conditional expression and a space between the conditional expression and block start. It's also convention to put a space between an object key and its value. And while both semi-colon and no-semicolon are common conventions, you should be consistent, using semicolons everywhere or nowhere
CodePudding user response:
Maybe a simpler approach would be by using do-while loop, something like this:
const axios = require('axios');
const callShipmentDetails = async (nextCall) => {
const res = await axios({...})
return res
}
const getShipmentDetails = ((url = "https://api.flipkart.net/sellers/v3/shipments/filter/") => {
var hasMore = false
// var times = 0
do {
var response = callShipmentDetails(url)
hasMore = response.data.hasMore
url = url.concat(response.data.nextPageUrl)
/*
this code is for breaking after 100 times if this becomes endless loop
*/
// times
// if (times > 100) break;
} while (hasMore)
});