1

Help guys im stuck. First of all im a beginner. This is my first react project

I have a form being sent with f_name, l_name, order order is an array of orders I am trying to loop through it and find the corresponding product then subtract the quantity for that order in the available stocks.


let Transaction = require("../models/transactionModel");
let Products = require("../models/userInventoryModel");

router.route("/add").post(async (req, res) => {
  const { f_name, l_name, order } = req.body;

  try {
    const newTransaction = new Transaction({
      f_name,
      l_name,
      order,
    });

    await order.forEach((order) => {
      let newProduct = Products.findOneAndUpdate(
        { product: order.product },
        { $inc: { stocks: -order.quantity } }
      );
      newProduct.save();
    });

    await newTransaction.save();
    res.status(200).json(newTransaction);
  } catch (error) {
    res.status(400).json(error.message);
  }
});
  • Please provide more details. What error are you getting, etc? – AdamExchange Jan 26 '21 at 19:54
  • I am getting the error in that try catch block. Everything was working well before I added the await order.forEach((order) line. Meaning the no problem with saving the transaction, just really having a problem in that foreach. – Jonathan Chiong Jan 26 '21 at 20:06
  • 1
    What error are you getting though? What's the error message, stack, etc? You may want to avoid using `forEach` with `async/await`. It is possible, but it's probably not doing what you think it is: https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – AdamExchange Jan 26 '21 at 20:12
  • @AdamExchange Thank you so much. I'll try to use for of tomorrow and see how it goes. – Jonathan Chiong Jan 26 '21 at 20:18
  • @AdamExchange i used for-of. it works. thanks for answering. please post ur answer. – Jonathan Chiong Jan 27 '21 at 07:17

1 Answers1

1

This code block:

await order.forEach((order) => {
  let newProduct = Products.findOneAndUpdate(
      { product: order.product },
      { $inc: { stocks: -order.quantity } }
  );
  newProduct.save();
});

Is probably not working as you would expect it. While it is valid code, it will not wait for each update to execute.

There are a few options - for / of or Array.map() that will work closer to how you would expect. See: Using async/await with a forEach loop for more details.

for (order of orders) {
   await Products.findOneAndUpdate(
      { product: order.product },
      { $inc: { stocks: -order.quantity } }
  );
}

Note this will run serially, updating one product at a time. This will be slower than .map which will run in parallel and would look like this.

const productUpdates = orders.map(order =>
  Products.findOneAndUpdate(
      { product: order.product },
      { $inc: { stocks: -order.quantity } }
  );
)

await Promise.all(productUpdates);

This will run each statement in parallel, which can cause more load on your database but will be faster. The tradeoffs depend on how many updates will be sent, database speed, and some other factors.

AdamExchange
  • 1,253
  • 1
  • 8
  • 16