Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

222
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda