Aaron Ullal Aaron Ullal - 4 months ago 14
Javascript Question

Javascript ES6 promise inside class function

After having read pages and pages about promises, I still cannot figure out the right way to return a promise (ES6 spec) inside a class function.

Here are the various options I've tried.

utils.getMyPhotos()
returns a promise.


1) Return the promise AND it's values


profilePictures(){
return utils.getMyPhotos().then(function(result){
var photosArray = result;
photosArray.forEach(function(element) {
this._list.push(new Picture(
element.src,
element.caption
));
}, this);
return this._list;

},function(error){
console.log(error);
return error;
});
}



2) Only return the promise' values


profilePictures(){
utils.getMyPhotos().then(function(result){
var photosArray = result;
photosArray.forEach(function(element) {
this._list.push(new Picture(
element.src,
element.caption
));
}, this);
return this._list;

},function(error){
console.log(error);
return error;
});
}



3)Create a new Promise and return it


profilePictures(){
return new Promise(function(fulfill,reject){
utils.getMyPhotos().then(function(result){
var photosArray = result;
photosArray.forEach(function(element) {
this._list.push(new Picture(
element.src,
element.caption
));
}, this);
fulfill(this._list);

},function(error){
console.log(error);
reject(error);
});
}
}


I try to use the above function as following :

pictures.profilePictures().then(function(result){
console.log("all good");
console.dump(result);
},function(error){
console.log("errors encountered");
console.log(error);
});


Hoever in the CLI I only see "errors encountered" followed by an empty
error
object.

What am I doing wrong?

Answer
  1. You are doing the right thing in here, but your error handler will not catch errors from its sibling success handler. I also would recommend that you don't mutate the instance variable this._list and return the result of doing this, as it is not clear from the function name that this is what it will do. Or maybe I'm being nit-picky. Anyway, see below for a recommended refactor.
  2. You are not returning anything.
  3. Is a Promise anti-pattern. Watch out for those.

______

Refactor of (1)

I have moved the error handler so that it will catch errors in all previous handlers. And we throw the error after logging it so we can catch errors on consumption of the API, rather than handling them internally. Though this may not be what you want to do, it means errors don't get swallowed mysteriously.

profilePictures () {
    return utils.getMyPhotos()
        .then(function (result) {
            return result.map(function (element) {
                return new Picture(element.src, element.caption);
            });
        })
        .then(null, function (error){
            console.log(error);
            throw err;
        });
}

Consume it:

instance.profilePictures()
    .then(function (pics) {
        pics.forEach(function (pic) {
            // Do something with the Picture instance
        });
    })
    .then(null, function (err) {
        // Handle the error
    });