Estoy trabajando en una aplicación web de comercio electrónico usando NodeJS y MongoDB (Mongoose).
Tengo una ruta de obtención que mostrará los productos en el carrito de compras y tengo problemas porque necesito completar una función antes de continuar con el resto del código.
La función empuja elementos a una matriz, y luego trato de representar una vista que pasa esa matriz, pero la matriz desaparece vacía.
Aquí está mi código.
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 }); } } }); }); Si registro la matriz antes de renderizar, la matriz está vacía.
Además, en la terminal, la matriz se registra incluso antes de que se ejecuten las consultas Mongoose.
Si registro la matriz dentro de la función que está presionando, la matriz se llena correctamente, pero es demasiado tarde para ser útil.
Cualquier ayuda sería muy apreciada.
Prueba algo como esto -
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); } }En su enfoque, lo que sucede es que está utilizando la función de devolución de llamada que no espera a que se ejecute el código dentro de forEach y simplemente continúa y devuelve la respuesta.
Async-await es un azúcar sintáctico en la parte superior que le permite escribir código de alguna manera, por lo que parece que se está ejecutando en serie. Otro método es usar promesas .
Necesita algo llamado promise-based behavior para su código. Consulte :