quielfala
quielfala

Reputation: 589

Mongoose query inside a forEach loop can't return or set value for sum variable

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

Answers (1)

Nice Books
Nice Books

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

Related Questions