Node Js Chaining the response

Viewed 285

I am trying to make a db call insides a loop and want to add that data into one object and then send this object to user, but I am getting only a empty object at the user end. I already checked this one asynchronous response into a loop in javascript NodeJS

router.get('/collection', (req, res) => {
    const Data = {}

     Section.find({})
           .then(sections => {
             sections.map(section => {
                  let id = section._id;
                   Product.find({section: id})
                         .then(products => {
                           // console.log(products)
                            Data[section.title] = {
                                title: section.title,
                                routeName: section.title,
                                id,
                                items: products
                            }
                            console.log(Data)
                         })
                         .catch(err => {
                            return res.status(500).json(err)
                         })

              })
              return res.json(data)
           })
           .catch(err => {
               return res.status(500).json(err)
           })
})

I want the output to be like :-

{
  food : {
           items: [...]
         },
  vegetable: {
            items: [...]
             }
}

food and vegetable are keys which will be obtained from a Database Call and items in each keys are returned from a seperate call to database.

1 Answers

return res.json(data) is executed before any of the mapped Product-promises are resolved (also there's a typo since you're returning data instead of Data). One way to do this is to map the find-promises and to use Promise.all on the mapped array. Something like:

router.get('/collection', (req, res) => {
    const Data = {}

    Section.find({})
    .then(sections => {
        const sectionProductPromises = sections.map(section => {
            let id = section._id;
            return Product.find({
                    section: id
                })
                .then(products => {                     
                    Data[section.title] = {
                        title: section.title,
                        routeName: section.title,
                        id,
                        items: products
                    }
                });

        });
        return Promise.all(sectionProductPromises);    
    })
    .then(() => {
        res.json(Data)
    })
    .catch(err => {
        res.status(500).json(err)
    });
});
Related