Promise.all with nested map.. First map only work others return empty objects in mongoose

Viewed 773

Promise.all with nested map.. First map only work others return empty objects in mongoose nodejs iam using only one promise.all to warp both maps

This this code

let foundCategory = await Category.findOne({_id: req.params.id})
 let CategoryWithSections =  {...foundCategory.toObject(),sectionsOfCategory: 
      //this map work    
     await Promise.all( foundCategory.sectionsOfCategory.map(async(SOC)=>{
                let sections=  await Section.findOne({_id: SOC.sectionOfCategory })
                return {...sections.toObject(), productsOfSections: 
                 //this map doesn't work 
    sections.productsOfSection.map(async(POS)=>{
                         return await Product.findOne({_id: POS.productOfSection })
                    })
                  }
            // return await sections.filter((section) => section._id === SOC.sectionOfCategory)
        }) )   } 
1 Answers

The productsOfSections object is filled with sections.productsOfSection.map which is array of promises. As your are not awaiting it, the promises are not instantly resolved.

The waiting for await is always bound to the most inner function it is in. Therefore the await Product.findOne({_id: POS.productOfSection }) is just bound to the async(POS)=>{ function, not to the async(SOC)=>{.

If you await all the promises in a similar way for the inner .map then it will create the "awaiting" chain which will returns you all the values

let foundCategory = await Category.findOne({
    _id: req.params.id
})
let CategoryWithSections = {
    ...foundCategory.toObject(),
    sectionsOfCategory:
        //this map work    
        await Promise.all(foundCategory.sectionsOfCategory.map(async (SOC) => {
            let sections = await Section.findOne({
                _id: SOC.sectionOfCategory
            })
            return {
                ...sections.toObject(),
                productsOfSections:
                    //this map doesn't work 
                    await Promise.all(sections.productsOfSection.map(async (POS) => {
                        return await Product.findOne({
                            _id: POS.productOfSection
                        })
                    }))
            }
            // return await sections.filter((section) => section._id === SOC.sectionOfCategory)
        }))
}

It is also good to mention that the async function just means that the function returns promise and then you are just working with the promises. It means that this part can be written without await and even without async function, because you are returning promise, therefore the result will be array of promises and thats something that Promise.all can work with

                await Promise.all(sections.productsOfSection.map((POS) => {
                    return Product.findOne({
                        _id: POS.productOfSection
                    })
                }))
Related