Attempting to create a final array with data pulled from 3 functions. The first two functions have all the data but then the 3rd function needs to run looping through one of the fields from function 2 in order to have the complete array at the end.
Looking for some advise and examples on how to fix this and or do it better. Have been advised promises would be a good solution but if someone could throw together a quick example so i can better get my head around it?
In my services controller i have this as the page http://domain.com/services/all and checks if the user is logged in.
exports.all = function(req, res){ if (!req.isAuthenticated()){ res.redirect('login'); } else {
Uses the services database schema in the model to connect to the database and pull out the info i need.
Database .find() .exec(function (err, services) { if (err) { return console.log(err); } if (!services) { console.log('Failed to load any Services'); }
Once the services are found (multiple RPC/API services that have the same commands but different data returned) then i ASYNC through each and connect.
async.mapSeries(services, function(service, cb) { connect(service); client.getBalance(req.user._id, 6, function(err, balance) { console.log(balance); if (err) balance = "Offline"; client.getAddressesByAccount(req.user._id, function(err, address) { console.log(address); if (err) address = "Offline";
Once the first two lots of data is returned (the first is just a string number and the second is an array of addresses then for each address i want to ASYNC again and run a third command and then map the result of each to the corresponding address from above and output a final array to pass to the view.
if(address != "Offline") { async.mapSeries(address, function (item, callback){ // print the key client.cmd('getreceivedbyaddress', item, 6, function(err, addressrecevied) { if (err) console.log(err); console.log(item + " = " + addressrecevied); // console.log(JSON.stringify(addressrecevied, null, 4)); }); callback(); // tell async that the iterator has completed }, function(err) { console.log('iterating done'); }); }; // console.log(service.abr + " address = " + address); console.log(service.abr + " balance = " + balance);
Callback that outputs the current top two results to the view variables.
return cb(null, { name: service.name, display: service.display, address: address, balance: balance, abr: service.abr, }); }); });
Function to call the view and pass variables when done.
}, function(err, services) { // console.log(services); if (err) { return console.log(err); } req.breadcrumbs('Services', '/services/all'); res.render('services/index', { title: 'Services', icon: 'iconfa-cog', summary: 'Services information', services: services, path : req.path, breadcrumbs: req.breadcrumbs(), udata : req.session.user }); }); }); }
}
WORK IN PROGRESS
exports.all = function(req, res){
if (!req.isAuthenticated()){
res.redirect('login');
} else {
Wallet
.find()
.exec(function (err, wallets) {
if (err) {
return console.log(err);
}
if (!wallets) {
console.log('Failed to load any Wallets');
}
async.mapSeries(wallets, function(coin, cb) {
//
// Q FUNCTION START
//
function getServiceBalance(service) {
connect(service);
cmd = Q.denodeify(client.cmd.bind(client)),
getBalance = Q.denodeify(client.getBalance.bind(client)),
getAddressesByAccount = Q.denodeify(client.getAddressesByAccount.bind(client));
client.getBalance(req.user._id, 6, function(err, balance) {
console.log("Service: " + service.name + " - Balance: " + balance);
if (err) balance = "Offline";
});
// We're going to fill this in step by step...
var result = {
name: service.name,
display: service.display,
abr: service.abr
};
return getBalance(req.user._id, 6)
.then(function (balance) {
result.balance = balance;
console.log("Balance:" + balance);
console.log("User ID: " + req.user._id);
return getAddressesByAccount(req.user._id);
})
.then(function (addresses) {
result.address = addresses;
console.log("Addresses:" + result.address);
if (!_.isArray(addresses)) {
// Throwing errors inside `then` is fine: they will get caught in `catch` below
throw new Error('Could not get addresses array');
}
// For each address, call getreceivedbyaddress and gather results in array
return Q.all(_.map(addresses, function (address) {
return cmd('getreceivedbyaddress', address, 6);
}));
}).then(function (addressesReceived) {
result.addressReceived = addressesReceived;
}).catch(function (err) {
// Here's the catch method--the *one and only* place all errors propagate to.
console.log(err);
result.balance = 'Offline';
result.address = 'Offline';
result.addressReceived = 'Offline';
}).thenResolve(result);
}
exec().then(function (services) {
if (!services) {
throw new Error('Failed to load any Services');
}
return Q.all(_.map(services, getServiceBalance), function (serviceBalances) {
req.breadcrumbs('Services', '/services/all');
res.render('services/index', {
title: 'Services',
icon: 'iconfa-cog',
summary: 'Services information',
services: serviceBalances,
path : req.path,
breadcrumbs: req.breadcrumbs(),
udata : req.session.user
});
});
}).done();
//
// Q FUNCTION END
//
});
});
}
}