AppleGrew AppleGrew - 2 months ago 6
AngularJS Question

Why is chaining `then` in Angular returning absurd result?

Take the below two tests. First test:-

var d = $q.defer();

d.promise.then(null, null)

.then(function () {
console.log('success');
}, function () {
console.log('fail');
});

d.reject(); // Prints fail, as expected


Second test:-

var d = $q.defer();

d.promise.then(null, function () {}) // Notice second argument is not null

.then(function () {
console.log('success');
}, function () {
console.log('fail');
});

d.reject(); // Prints success!


Why in second test I am getting 'success' message?

JSFiddle - https://jsfiddle.net/7agszh95/

Answer

In the second case you passed in a failure handler in the first call to .then(). That function is assumed to have handled the error so whatever it returns is passed in to the success handler for the next promise in the chain (except when it returns a promise and then the next promise in the chain will get the result of resolving or rejecting the returned promise).

If you want a failure handler but don't want it to mark the problem as resolved you need to return a value that indicates a further failure. return $q.reject() is the simplest way to do this although you might also want to propagate the actual error:

var d = $q.defer();

d.promise.then(null, function (err) {
    return $q.reject(err); // Indicate that we didn't manage to handle the error
})

.then(function () {
    console.log('success');
}, function (err) {
    console.log('fail: '+err);
});

d.reject('some error');