Reputation: 843
I am developing a api using Loopback and I develop some remote method to retrieve data from efferent modules and rearrange the data as I wish. This is my sample code.
mainModule.viewAll = function(cb) {
var mainFilter = {fields: ['f_name', 'l_name', 'id'], where: {status: 1}};
var cEmp = null;
mainModule.find(mainFilter, function(err, mainModules) {
var returnArray = [];
var returnEle;
var secondModule = app.models.secondModule;
mainModules.forEach(emp=>{
returnEle = {};
returnEle['name'] = emp.name;
secondModule.count({ where: { type: 1 }}, function (err, count) {
returnEle['field1'] = count;
console.log(count);
});
secondModule.count({ where: { type: 1 } }, function (err, count) {
returnEle['field2'] = count;
console.log(count);
});
secondModule.count({ where: { type: 1 } }, function (err, count) {
returnEle['field3'] = count;
console.log(count);
});
returnArray.push(returnEle);
});
cb(null, returnArray);
});
};
mainModule.remoteMethod('viewAll', {
'http': {'verb': 'get', 'path': '/viewAll'},
returns: {arg: 'profiles', type: 'Array'},
});
And my response is like this,
{
"profiles":[
{
"name":"Jhone",
"id":1
},
{
"name":"Shaam",
"id":2
},
{
"name":"Viki",
"id":3
}
]
}
As you see here it only responce with the name and id fields no details about 'filed1', 'field2', 'field3'.But in console log 'field1','field2','field3' displaying perfectly.
I found that the reason could be the asynchronous behavior of the JavaScript. I study on some methods to fix this problem like using callback function, Promise etc. but none of those are fit with situation. (Promises seams little more efficient, so I tried to wrap the second module functions with the one promise and entire 'for each' function to another promise and cb(null, returnArray);
was set to the then function. But it also didn't work).
I am new to the Loopback, So if someone know the answer please help me.
Upvotes: 0
Views: 781
Reputation: 4678
Use async.eachOf to apply async operation on each modules, then for each modules, use async.parallel to compute your 3 count in parallel :
var returnArray = [];
async.eachOf(mainModules, function(module, index, acb){
// for each module do parallel count
async.parallel({
field1: function(pcb){
secondModule.count({ where: { type: 1 }}, pcb);
},
field2: function(pcb){
secondModule.count({ where: { type: 1 } }, pcb);
},
field3: function(pcb){
secondModule.count({ where: { type: 1 } }, pcb);
}
}, function(err, result){
// final parallel callback, when all parallel count are finished
if(err || !result)
{
return acb(err || true);
}
else
{
result.name = module.name;
// here result contains the 3 count in result["field1"], result["field2"] and result["field3"]
returnArray.push(result);
return acb(null);
}
})
}, function(err){
// final async.each of callback when all modules are proceed
if(err)
{
// do stg
}
else
{
return cb(null, returnArray)
}
})
Upvotes: 1