Reputation: 12048
I'm new to Promises so I might be doing something stupid here, but I can't seem to figure it out.
Just so I know I'm on the right path, a bit of information upfront. I have an authenticate method which returns a promise:
APIWrapper.prototype.authenticate = function() {
var self = this;
return new Promise(function(resolve, reject) {
request({
uri: self.httpUri + '/auth/authenticate',
method: 'GET',
headers: {
auth_user: self.user,
auth_pass: self.pass,
auth_appkey: self.appkey
}
}, function(err, res, body) {
if (err) return reject(err);
self.parser.parseXML(body, function(err, result) {
if (err) return reject(err);
if (result.error) { return reject(result.error) }
self.token = result.auth.token[0];
return resolve(result);
});
});
});
};
I chain this with .getDashboards()
like this:
wrapper.authenticate().then(function() {
wrapper.getDashboards();
}).then(function(result) {
console.log('result', result);
});
.getDashboards()
also returns a promise:
APIWrapper.prototype.getDashboards = function() {
var self = this;
return new Promise(function(resolve, reject) {
request({
url: self.httpUri + '/user/dashboard',
method: 'GET',
headers: {
auth_appkey: self.appkey,
auth_token: self.token
}
}, function(err, res, body) {
if (err) { return reject('Could not connect to the API endpoint'); };
self.parser.parseXML(body, function(err, data) {
var dashboards = [];
if(err) { return reject(err); }
if(data.error) { return reject(data.error); }
for(var i = 0; i < data.Dashboards.Dashboard.length; i++) {
dashboards.push(self.getDashboard(data.Dashboards.Dashboard[i]));
}
// returns early here
resolve(dashboards);
});
});
});
};
With the .getDashboard()
method like this at the moment:
APIWrapper.prototype.getDashboard = function(db) {
var dashboard = {};
dashboard.title = db.Title[0];
dashboard.id = db.$.id;
console.log(dashboard);
return dashboard;
};
What happens with this code is that it returns the result
before it returns the dashboards. I suspect the resolve()
in .getDashboards()
doesn't wait for the for
loop to finish? Do I need to use promises in the .getDashboard()
method as well, or how would I wait for it to finish before resolving my .getDashboards()
promise?
Output:
> result undefined
{ title: 'Dashboard 1', id: '3271' }
{ title: 'Dashboard 2', id: '3272' }
{ title: 'Dashboard 3', id: '3273' }
I'm using this Promise implementation at the moment: https://github.com/then/promise
Upvotes: 3
Views: 159
Reputation: 382444
You need to return the promise to have it chained :
wrapper.authenticate().then(function() {
return wrapper.getDashboards();
}).then(function(result) {
console.log('result', result);
});
In your case, it can be simplified as
wrapper.authenticate()
.then(wrapper.getDashboards)
.then(function(result){
console.log('result', result);
});
You also don't seem to handle errors. The then
library seems very raw on this point, so you should probably add a second argument :
wrapper.authenticate()
.then(wrapper.getDashboards, onAuthenticateError)
.then(function(result){
console.log('result', result);
}, onDashboardError);
Upvotes: 2