1

Sometimes I have trouble to fetch my data using $http service. And I did not 100% understand the main difference between .success() and .then()

The following is an example that I can fetch the data using $http().then(), but I can't fetch my data using $http().success(). Can anyone explain why?

Code using $http.success() http://jsfiddle.net/xoonpLte/11/

var manuRep = angular.module('manuRep', ['ui.bootstrap']);
  manuRep.controller('MyAppController', function($scope, $http) {
    $http.get('https://dl.dropboxusercontent.com/u/59954187/jobs.json').
      success(function(response) {
        $scope.cats = response.data;    
      }).
      error(function(error){
        alert(JSON.stringify(error));
      return error;
      });
  });

Code using $http.then() http://jsfiddle.net/xoonpLte/12/

var manuRep = angular.module('manuRep', ['ui.bootstrap']);
  manuRep.controller('MyAppController', function($scope, $http) {
    $http.get('https://dl.dropboxusercontent.com/u/59954187/jobs.json').
      then(function(response) {
        $scope.cats = response.data;    
      });
  });
Shaohao
  • 3,471
  • 7
  • 26
  • 45

4 Answers4

4

.then is a promises

.success and .error is a callback.

Why callbacks or Promises?

1 . Promises can handle global errors.
2 . Promises can be chained (you don't have this encapsulation like callbacks)

P = promise,
R = response,
E = error.

1:

P1(R1)
.P2(R2)
.P3(R3, E3)  

Error 3 will be called if there is an error in promise 1, 2 or 3.
That is not possible with callbacks.

2:
If you have 3 promises:

P1(R1, E1)
.P2(R2, E2)
.P3(R3,E3)

If you have 3 callbacks

P1().success(P2().success(P3().success().error()).error()).error()

EDIT

.service('Auth', function(){
  this.isLoggedIn = function(){
     return $http.get('url/isLoggedIn');
  };
})

.service('getData', function(){
  this.name = function(){
    return $http.get('url/data/name');
  }
})

.controller('MyCTRL', ['Auth', 'getData', function(auth, getData){

   Auth.isLoggedIn().then(function(resp){
     return getData.name(); //By sending a value back inthe response, next response is called
   })
   .then(function(res){
        //Here we are
    }, function(err){
        //Global error.
        //This will be called in P1 or P2
    })


}]);
gr3g
  • 2,866
  • 5
  • 28
  • 52
  • Can you give an example when I have to chain promises? – Shaohao Jul 14 '15 at 14:09
  • 1
    @ShaohaoLin when you want to perform other asynchronous actions, or data manipulation, after a promise is resolved, without exposing that information to the person consuming the promise. For example, your service may want to chain promises to transform a response into a certain object, but your controller doesn't really care about all those intermediate steps. – Dan Jul 14 '15 at 14:14
  • So the logic is, I check if the user log in or not, then get the name of the user. Is that correct ? – Shaohao Jul 14 '15 at 14:31
  • Absolutely. (This is just an example) – gr3g Jul 14 '15 at 14:45
3

As per the documentation: https://docs.angularjs.org/api/ng/service/$http

The .then() function is the standard way to register callbacks for when a promise has been resolved - see https://docs.angularjs.org/api/ng/service/$q for angular's implementation of promises.

The promise returned by $http is a promise for a Response:

$http.get('http://example.com').then(function successCallback(response) {
response.data, response.status, and so on
})

Oftentimes, all you need from the Response is just the data. The callbacks registered via .success() will receive just data:

$http.get('http://example.com').success(function successCallback(data) {
data.??? depending on what you return
})
Kurt
  • 196
  • 1
  • 14
1

Success returns data already, in your case it returns cats, so effectively you're assigning property data on cats. On the other hand, in the second example the data are part of the response, so cats are in response.data.

To understand the difference between $http().then() and $http().success(), I'd recommend this great article: http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/

Robert Goldwein
  • 5,805
  • 6
  • 33
  • 38
1

The other answers touch on how success receives just the data, but then doesn't. However, the implication is far more than that:

$http() (or any of it's shortcut methods) will return a promise that has had its prototype augmented. The prototype gains the success and error methods. Both of these methods essentially function more like callbacks than anything else; whilst invoking success and passing it a callback will return the original promise back, that's where the similarities with promises end.

success/error cannot be chained. That is, when you return a value from then in a promise, it will be passed to the next invocation of then. In this sense, promises can be chained. In addition, returning a promise in a then will resolve that promise before passing the resolved value to the next then invocation.

success/error cannot do this, they are instead used to introduce side effects. Any values you return from these functions are discarded. They also do not receive the raw http response, but instead just the data from the endpoint. Multiple success/error calls will set up independent callbacks. In addition, there is no way to 'wait' for a success/error callback to have been finished executing. So Q.all() won't work on success/error callbacks if those success/error callbacks fire off async events.

As a result I would recommend you only use then/catch in place of success/error. This allows you to keep compatibility with other frameworks that handle promises, and also will allow you to chain promises to further manipulate data. It also helps you prevent side effects, and everyone loves preventing side effects!

Dan
  • 10,282
  • 2
  • 37
  • 64
  • As you mention side effects, I don't quite understand side effects. What do you mean side effects beside any values return from functions are discarded? – Shaohao Jul 14 '15 at 14:37
  • A side effect is when a function does something affecting external state, essentially. A basic example would be logging to a console. Using `success`/`error` can create side effects which become difficult to track down and make your application harder to reason about. – Dan Jul 14 '15 at 16:24