AngularJS : promises, can you pass a promise back after using .then()?

Issue

I’m still new to Angular and promises so I hope I have the correct idea here.

I currently have a data layer service which uses restangular to get some data, then returns a promise, like this…

dataStore.getUsers = function (params) {
    return users.getList(params);
};

Then, my controller which has called this function receives a promise back, like this…

$dataStore.getUsers(params).then(function (response) {
    $scope.users = response;
}, function(response) {
    $log.error("Get users returned an error: ", response);
});

This is working well, but I’d like to use the promise inside of my datastore before passing it back. I’d like to use the .then() method to check if it failed and do some logging, then, from the sucess function and from the failure function I’d like to return the original promise back to my controller.

My controller would then be able to use the .then() method like it already is, in fact, I don’t want my controller code to change at all, just my datastore code.

Here’s some semi-pseudo code to show what I’d like my datastore function to do…

dataStore.getUsers = function (params) {

    users.getList(params).then(function (response) {
        $log("server responded")
        return original promise;
    }, function(response) {
        $log.error("server did not respond");
        return original promise;
    });

};

Solution

You were actually not far off at all in your pseudo code. Promises chain:

dataStore.getUsers = function (params) {
    return users.getList(params).then(function (response) {
        $log("server responded")
        return response;
    }, function(failure) {
        $log.error("server did not respond");
        // change to throw if you want Angular lever logs
        return $q.reject(failure); 
    });

};

The controller now gets resolved/rejected with the same value. The log requires tapping into the promise so you must add a .then handler to deal with it. Other promise libraries have convinicene methods for this but $q is minimalistic in this regard.

Alternatively, you can use nicer catch syntax, as well as propagate the errors to your logs:

dataStore.getUsers = function (params) {
    return users.getList(params).then(function (response) {
        $log("server responded")
        return response;
    }).catch(function(failure) {
        $log.error("server did not respond");
        throw failure;
    });

};

Answered By – Benjamin Gruenbaum

Answer Checked By – Robin (AngularFixing Admin)

Leave a Reply

Your email address will not be published.