0

With the following function I am trying to calculate the total price of a checkout. But if I console.log() the variable before it is returned, I get 0. If I console.log() the variable in the findOne() function, I get the correct value.

As database I use MongoDB and "Item" is a model.

function calculateOrderAmount(items) {
  var totalPayment=0;
  items.forEach((item) => {
    Item.findOne( { _id: item } )
      .then(item => {
          if(item) {
            // Item exists
            totalPayment = item.price;
            console.log(totalPayment);
          }
      });
  });
  console.log(totalPayment);
  return totalPayment;
}

I'm desperate about it and I don't really know what to look for on the internet. Many thanks for answers in advance.

Holla
  • 21
  • 5

1 Answers1

0

Item.findOne is an async operation, so in your code you execute:

  • var totalPayment = 0
  • items.forEach((item) => {...
  • console.log(totalPayment)
  • return totalPayment
  • other sync code who called calculateOrderAmount
  • then the callback of Item.findOne is run

You must use a callback sytle or an async function like this:

async function calculateOrderAmount (items) {
  // beware: if you have a huge items list, doing so could lead to high memory usage
  const itemsPromises = items.map((item) => {
    return Item.findOne({ _id: item })
    .then(item => {
      if(item) {
        // Item exists
        return item.price;
      }
      return 0
    });
  })

  const prices = await Promise.all(itemsPromises)
  const totalPayment = prices.reduce((a, b) => a + b, 0)
  console.log(totalPayment)
  return totalPayment
}
Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73