I want to make multiple requests in node.js to get a couple of external API responses, to combine them into one array. I'm using a for loop to achieve this. Here's my code:
res.setHeader('Content-Type', 'application/json');
const sub = req.query.days_subtract;
const enddate = req.query.end_date;
var array = [];
for (var i = 0; i < sub; i++) {
request("https://api.nasa.gov/planetary/apod?date=" + subtractDate(enddate, i) + "&api_key=DEMO_KEY", function(error, response, body) {
array.push(body);
// console.log(body);
});
}
res.send(array);
but this piece of code returns [] all the time. I know it's because the for loop only starts these async requests, but it doesn't wait for them to finish. I tried to use async/await but that didn't work either. So how to wait for this loop to finish getting requests and to finish pushing them to the array so it can be shown to users?
For your use case, using await
with Promise.all
is probably the most performant way to go about it. Your code should look something like this:
res.setHeader('Content-Type', 'application/json');
const sub = req.query.days_subtract;
const enddate = req.query.end_date;
var promiseArray = [];
for (var i = 0; i < sub; i++) {
promiseArray.push(new Promise((resolve, reject) => {
request("https://api.nasa.gov/planetary/apod?date=" + subtractDate(enddate, i) + "&api_key=DEMO_KEY", function(error, response, body) {
if (error) reject(error);
else resolve(body)
})
}))
}
res.send(await Promise.all(promiseArray));
As others have said, you should probably use Promise
for your asynchronous code, and the async / await
syntax is very legible.
However, you seem to prefer using callbacks. In that case, you could write your code this way :
res.setHeader('Content-Type', 'application/json');
const sub = req.query.days_subtract;
const enddate = req.query.end_date;
var array = [];
var resultsCount = 0;
for (var i = 0; i < sub; i++) {
request("https://api.nasa.gov/planetary/apod?date=" + subtractDate(enddate, i) + "&api_key=DEMO_KEY", function(error, response, body) {
if (error) { res.status(500) }
array[i] = body
// console.log(body);
resultCount++;
if (resultCount === sub) {
res.send(array);
}
});
}
Basically, the idea is to call the res.send
method only once all requests have returned their result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With