Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

221
Views
How to stop execution until function finishes

I'm working on an e-commerce web app using NodeJS and MongoDB (Mongoose).
I have a get route that will show products in shopping cart, and I'm struggling because I need one function to complete before continuing with the rest of the code.
The function pushes items to an array, and then I try to render a view passing that array, but the array goes away empty.

Here's my code.

router.get('/cart', function (req, res) {
  User.findOne({ username: req.user.username }, function (err, doc) {
    // This is the array that needs to be passed
    const prodAndQty = [];
    const prodEntries = Object.entries(doc.shoppingCart);
    // This is the function that I need to complete before continuing
    prodEntries.forEach(function (entry) {
      Product.findOne({ id: entry[0] }, function (err, doc) {
        prodAndQty.push([doc, entry[1]]);
      });
    });
    if (err) { console.log(err); }
    else {
      // If I log here, the array is empty.
      console.log(prodAndQty);
      if (doc) {
        res.render('cart', { doc: doc, qty: prodEntries.length, products: prodAndQty });
      } else {
        res.render('cart', { doc: null, qty: 0, products: null });
      }
    }
  });
});

If I log the array before rendering, the array is empty.
Also, in the terminal, the array is logged even before the Mongoose queries executes.

Terminal log

If I log the array inside the function that is pushing, the array is filled correctly, but it's too late to be useful.

Any help would be greatly appreciated.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Try something like this -

router.get('/cart', async function (req, res) {
    try {
        const doc = await User.findOne({ username: req.user.username });

        if(!doc) {
            res.render('cart', { doc: null, qty: 0, products: null });
        }

        const prodEntries   = Object.entries(doc.shoppingCart);

        // Instead of one by one searching, I used `in` operator (you can do one by one too, if you want)
        const entires       = prodEntries.map((prod) => {
            return prod[0];
        })

        const prodAndQty    = await Product.find({ id : { $in : entires }});
        // TODO - Modify this prodAndQty array as you want

        res.render('cart', { doc: doc, qty: prodEntries.length, products: prodAndQty });

    } catch(err) {
        throw new Error(err);
    }
}

In your approach, what happens is, you are using callback function which does not wait for the code to execute inside forEach and it just go ahead and returns the response.

Async-await is a syntactic sugar on the top of that which let you write code in a way, so it seems it's executing in serial manner. Another method is to use promises.

about 4 years ago · Juan Pablo Isaza Report

0

You need something called as promise-based behavior for your code. Please refer :

  1. async functions
  2. promise
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!