pb36
pb36

Reputation: 410

Wait for mongoose.find inside foreach loop inside callback

How do I wait till data is populated in finalresult before going further? I tried async and await but did not work as expected and on top of that I am new to nodejs express

exports.getporderlist = (req, res) => {
  page = req.params.page || "1";
  skip = (page - 1) * 10;
  if (req.profile.role.includes(1)) {
    Order.find({ status: { $in: [0, 2] } })
      .select("_id updatedAt items salesman")
      .populate("customer", "customer_name phone")
      .sort({ updatedAt: -1 })
      .skip(skip)
      .limit(10)
      .exec((err, orders) => {
        if (err) {
          return res.status(400).json({
            error: "No Orders found",
          });
        }

        let finalresult = [];

        orders.forEach((oelement) => {
          total = 0;
          salesman = oelement.salesman.split(" ")[0];
          itemscount = oelement.items.length;
          placeorder = true;
          oelement.items.forEach((element) => {
            total += element.price * element.quantity;
          });
          //Wait for the bellow data variable to finish populating finalresult 
          const data = Design.find()
            .select("_id sm lm")
            .where("_id")
            .in(oelement.items)
            .exec((err, orders) => {
              finalresult.push(orders);
              console.log(orders);
            });
});
        console.log(1);
        res.json(finalresult);//getting empty finalresult array on call
      });
  } else {
    res.json({ Message: "Go away" });
  }
};

Upvotes: 1

Views: 777

Answers (1)

Mohammed Amir Ansari
Mohammed Amir Ansari

Reputation: 2401

The exec() function do returns promise, so you can user async/await to call it. Your code will look like this:

exports.getporderlist = async (req, res) => {
    try {
        if (req.profile.role.includes(1)) {
            page = Number(req.params.page) || 1;
            skip = (page - 1) * 10;
            const orders = await Order.find({
                    status: {
                        $in: [0, 2]
                    }
                })
                .select("_id updatedAt items salesman")
                .populate("customer", "customer_name phone")
                .sort({
                    updatedAt: -1
                })
                .skip(skip)
                .limit(10)
                .exec();
            let finalresult = [];

            for (const oelement of orders) {
                let total = 0;
                salesman = oelement.salesman.split(" ")[0];
                itemscount = oelement.items.length;
                placeorder = true;
                oelement.items.forEach((element) => {
                  total += element.price * element.quantity;
                });

                const data = await Design.find()
                    .select("_id sm lm")
                    .where("_id")
                    .in(oelement.items)
                    .exec();
                finalresult.push(data);
            }
            res.json(finalresult);

        } else {
            res.json({
                Message: "Go away"
            });
        }
    } catch (err) {
        return res.status(400).json({
            error: "No Orders found",
        });
    }
}

you can always call async functions with async/await inside for ..of loops. You can read more here

P.s. Couldn't get a chance to run the code.. Let me know if you have any doubts :)

Upvotes: 1

Related Questions