Since a function that returns a promise is asynchronous, how would you use it inside of a forEach loop? The forEach loop will almost always finish before the data being fetched or manipulated by the promise returning function can complete its data manipulation.
Here is an example of some code where I am having this problem.
var todaysTopItemsBySaleFrequency = [];
listOfItemIdsAndSaleFrequency.forEach((item) => {
Product.findById(item.itemId).then((foundItem) => {
var fullItemData = foundItem.toJSON();
fullItemData.occurrences = item.occurrences;
todaysTopItemsBySaleFrequency.push(fullItemData);
});
});
return res.status(200).json(todaysTopItemsBySaleFrequency);
The array called todaysTopItemsBySaleFrequency is sent back to the client empty. findById is a mongoose function which returns a promise, so it doesn't fully populate the array by the time the response is sent back to the client.
You cannot use a forEach
loop, as that works only with functions that don't return anything. If they return something, or a promise for it, you'll have to use a map
loop. You then can use Promise.all
on the result, the array of promises:
Promise.all(listOfItemIdsAndSaleFrequency.map(item =>
Product.findById(item.itemId).then(foundItem => {
var fullItemData = foundItem.toJSON();
fullItemData.occurrences = item.occurrences;
return fullItemData;
})
)).then(todaysTopItemsBySaleFrequency => {
res.status(200).json(todaysTopItemsBySaleFrequency);
})