0

i'm writing a webshop in Node with Express and Mongoose. The Mongoose Models are "Product" and "Item". Every Item belongs to a Product. I want to count the Items of a Product (Stock) and serve this information to the view.

The Problem is, that the res.render part is executed before the forEach Loop is done. So "product.stock" is undefined

exports.getProducts = (req, res, next) => {
    Product.find()
        .lean()
        .then(products => {

            products.forEach(product => {
                Item.countDocuments({productId: product._id})
                    .then( count => {
                        product.stock = count
                    })
            });

            res.render('shop/product-list', {
                path: '/products',
                pageTitle: "All Products",
                products: products
            })
        })
        .catch(err => { return next(err) })
};

1 Answer 1

1

Try using async/await:

exports.getProducts = (req, res, next) => {
    Product.find()
        .lean()
        .then(async (products) => {
            await Promise.all(products.map(async (product) => {
                product.stock = await Item.countDocuments({productId: product._id});
            });

            res.render('shop/product-list', {
                path: '/products',
                pageTitle: "All Products",
                products: products
            })
        })
        .catch(err => { return next(err) })
};

I changed forEach to map so that your list of Product would be converted into a list of Promise. Then Promise.all waits until all of the Promises have completed, which will occur when product.stock has been set for each product. Only then will res.render() be called.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.