Reputation: 589
I'm trying to calculate sum of each price of product queried from the db, using findById. Where the id is from array of objects that I iterate using forEach loop.
module.exports.checkoutOrder = (reqBody, buyerId, isAdmin)=>{
let sum =0;
reqBody.items.forEach(item=>{
Product.findById(item.productId,(error, result)=>{
//console.log(result.price);
sum += result.price;
})
}) console.log(sum);
The problem is, is I can't seem to get or set any variable inside the findById block. Even if I put return on the sum variable, it's always the same result 0. I'm sure that my query is returning a data when I console.log result.price.
I know there are other ways to sum data, I just want to know first why it doesn't work this way?
Upvotes: 1
Views: 701
Reputation: 1861
The 2nd argument of findById (err,result)=>{}
is a callback, which by nature does not run immediately. console.log(sum)
runs before all callbacks & hence prints 0.
You need to wait until all callbacks have run. A crude solution would be to wrap the console.log(sum)
inside a setTimeout
with a reasonable delay.
A better solution would be use use the exec
method to create Promise objects Promise.all
method to wait for all promises to complete.
let promiseList = await reqBody.items.map(async (item,i)=>
Product.findById(item.productId).exec()
);
Promise.all(promiseList).then((productList)=> {
let sum = productList.reduce((acc,product)=> acc + product.price, 0);
console.log(sum);
});
Upvotes: 1