Reputation: 125
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
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