Marisco
Marisco

Reputation: 125

Node API - res.send() from 2nd loop

I'm trying to return the hole master/detail object to client, but detail is coming as an empty array Like this post I've also ended with the same problem:

"Can't call res.send(data) inside the loop because res.send() can only be called once." "But if I call res.send(array) outside of the loop, the array is still empty"

What is the right way to do it? I'm trying not to use use asyn

    var getMasterDetail = function (req, res) {

        const key = "Detail";
        var list = {}
        list[key] = []
        var modelsMaster = objModels.ObjMaster
        var modelsDetail = objModels.objDetail
         modelsMaster.getMasters(objModels.hdb, (e, master) => {
            if (e) {
                return console.log(e);
            }              

            for (i = 0; i < master.length; i++) {
                modelsDetail.getDetails(objModels.hdb, master[i].nrMaster, (e, detail) => {
                    if (e) {
                        return console.log(e);
                    }

                    for (j = 0; j < detail.length; j++) {

                        list[key].push(detail[j])
                    }

                })
                master[i].DetailList = list           
            };

            res.send({ MasterDetail: master })

        })

    };

Thanks.

UPDATE: The answer from @Hammerbot was almost right, but, I have not notice at the time, that I was getting the same detail for all masters. Ex. {master:{1,2,3,4,5,6}, master{1,2,3,4,5,6}} instead of {master:{1,2,3}, master{4,5,6}}

I Have no any idea why and how to fix it. I've tried to clean the list befor the loop, and move master master[i].DetailList, creating a second Promisse for the second loop, no success.

Upvotes: 0

Views: 148

Answers (1)

Hammerbot
Hammerbot

Reputation: 16354

You should use promises for that. Here is an example that should resolve your problem:

var getMasterDetail = function (req, res) {

    const key = "Detail";
    var list = {}
    list[key] = []
    var modelsMaster = objModels.ObjMaster
    var modelsDetail = objModels.objDetail
    modelsMaster.getMasters(objModels.hdb, (e, master) => {
        if (e) {
            return console.log(e);
        }

        const promises = []

        for (i = 0; i < master.length; i++) {
            const promise = new Promise(resolve => {
                master[i].DetailList = list
                modelsDetail.getDetails(objModels.hdb, master[i].nrMaster, (e, detail) => {
                    if (e) {
                        return console.log(e);
                    }

                    for (j = 0; j < detail.length; j++) {
                        list[key].push(detail[j])
                    }
                    resolve()
                })
            })

            promises.push(promise)
        }

        Promise.all(promises).then(() => {
            res.send({ MasterDetail: master })
        })
    })

};

As you can see, before the loop I initiate a promises array. Inside the loop, I create a promise by iteration that gets resolved when the callback has finished.

I push the promise into the promises Array, and at the end I use Promise.all() to wait for all the promises to get resolved before sending the result in the response.

Upvotes: 1

Related Questions