2

I'm reading AngularJS Up and Running. In chapter 6, it mentions handing errors from promises like this:

$http.get('/api/server-config').then(function(configResponse) {
    return $http.get('/api/' + configResponse.data.USER_END_POINT);
}).then(function(userResponse) {
    return $http.get('/api/' + userResponse.data.id + '/items');
}).then(function(itemResponse) {
    // Display items here
}, function(error) {
    // Common error handling
});

And in other places, I see .catch() being used (for example, the answer here: Assigning variable from a factory to a control doesn't work uses .catch() like so:

BaseService.fetch.stuffs
.then(function(data) {
    self.stuffies = data;
    console.log(self.stuffies);
}).catch(function(errorResponse) {
    self.cerrorMessages = errorResponse.data;
});

My question is, what's the difference between the above menthod and the method shown in the book:

BaseService.fetch.stuffs
.then(function(data) {
    self.stuffies = data;
    console.log(self.stuffies);
}, function(error) {
    self.cerrorMessages = errorResponse.data;
});

What's preferred?

Community
  • 1
  • 1
SilentDev
  • 20,997
  • 28
  • 111
  • 214

3 Answers3

2

The Difference:

If there is some error from service api then function(error) {} will catch it.

But if your success method function(data){} throws some error then only .catch() can caught it.

Example:

promise().then(function (data) {
  throw new Error('execption from success');
}).catch(function (err) {
  // execption from success caught!!
});

promise().then(function (data) {
  throw new Error('execption from success');
}, function (error) {
  // execption from success : NOT caught
});

Read more

The Preferred one :

promise().then(function (data) {
 // handle data
}, function (error) {
  // handle error from api
}).catch(function (err) {
  // handle error from response.
});
anoop
  • 3,812
  • 2
  • 16
  • 28
0

According to AngularJS 1.2 documentation

catch(errorCallback) – shorthand for promise.then(null, errorCallback)

It means you can use the 2 syntaxes interchangeably.

Hoa
  • 3,179
  • 1
  • 25
  • 33
  • This is not what the OP asks. It is basically 1 then vs 2 thens. And this question is surely a dupe because it was discussed on SO numerous times. – Estus Flask Apr 01 '17 at 11:32
0

The catch syntax is better as it separate the error handling to its own and single channel, away from the control flow, it is considered as good practice, promoted by bluebird.js and others, while the use of an error handler function as the second parameters of the then function can be considered as an anti-pattern.

You can find some really good read about them:

http://www.datchley.name/promise-patterns-anti-patterns/

http://taoofcode.net/promise-anti-patterns/

https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns

The different between the two can be illustrated via an example. As for first piece of code you posted:

$http.get('/api/server-config').then(function(configResponse) {
    // create another promising chain here
    $http.get("/something-else").then(function(response) {
       // Do something
    }); 
    return $http.get('/api/' + configResponse.data.USER_END_POINT);
}).then(function(userResponse) {
    return $http.get('/api/' + userResponse.data.id + '/items');
}).then(function(itemResponse) {
    // Display items here
}, function(error) {
    // Common error handling
});

If instead of just returning the promise, I call another async function inside the first promise resolver, the error from this function will never reach the last error handler, if I forget to handle the error from that new function separately, it will be swallowed.

However, this problem can be fixed using a catch:

$http.get('/api/server-config').then(function(configResponse) {
    // create another promising chain here
    $http.get("/something-else").then(function(response) {
       // Do something
    }); 
    return $http.get('/api/' + configResponse.data.USER_END_POINT);
}).then(function(userResponse) {
    return $http.get('/api/' + userResponse.data.id + '/items');
}).then(function(itemResponse) {
    // Display items here
}).catch(function(error) {
    // error from nested function something else, can also be handled here 
    // within a single error handling channel
});
Thai Duong Tran
  • 2,453
  • 12
  • 15
  • are you sure it works like that? have you tried it? I don't see how the error from the nested function can ever bubble up to the handler. In fact, I think the two of your examples are identical and just use slightly different syntax. – fdreger Apr 01 '17 at 10:41