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.
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)
}
})