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 examp
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
})
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/
.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
})
}]);
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!