48

I'm reading a book called, "Pro Angular JS". However, I have a question about how to catch a status of error.

What I coded is :

$http.get(dataUrl)
    .success(function (data){
        $scope.data.products = data;
    })
    .error(function (error){
        $scope.data.error=error;
        console.log($scope.data.error.status); // Undefined!
        // (This is the spot that I don't get it.)                                         
    });

If I code "console.log($scope.data.error.status);" , why does the argument of console.log is undefined?

In the book, there are sentence, "The object passed to the error function defines status and message properties."

So I did $scope.data.error.status

Why is it wrong?

nujabes
  • 891
  • 2
  • 8
  • 17
  • What is the message if you just do `console.log($scope.data.error);`? – Clawish Dec 16 '14 at 15:13
  • @Clawish Then, "Not Found" is printed. However, What I want to print is "404" – nujabes Dec 16 '14 at 15:14
  • Thank you for all guys!! Because there were so many helpful answer even though it's my first question in this site, I'm so happy! It's really good site!! – nujabes Dec 16 '14 at 15:25
  • success and error have been deprecated: http://stackoverflow.com/questions/35329384/why-are-angular-http-success-error-methods-deprecated-removed-from-v1-6 – Christophe Roussy Mar 29 '17 at 09:19

6 Answers6

73

The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. Have a look at the docs https://docs.angularjs.org/api/ng/service/$http

Now the right way to use is:

// Simple GET request example:
$http({
  method: 'GET',
  url: '/someUrl'
}).then(function successCallback(response) {
    // this callback will be called asynchronously
    // when the response is available
  }, function errorCallback(response) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
});

The response object has these properties:

  • data – {string|Object} – The response body transformed with the transform functions.
  • status – {number} – HTTP status code of the response.
  • headers – {function([headerName])} – Header getter function.
  • config – {Object} – The configuration object that was used to generate the request.
  • statusText – {string} – HTTP status text of the response.

A response status code between 200 and 299 is considered a success status and will result in the success callback being called.

visar_uruqi
  • 2,484
  • 1
  • 23
  • 20
49

Your arguments are incorrect, error doesn't return an object containing status and message, it passed them as separate parameters in the order described below.

Taken from the angular docs:

  • data – {string|Object} – The response body transformed with the transform functions.
  • status – {number} – HTTP status code of the response.
  • headers – {function([headerName])} – Header getter function.
  • config – {Object} – The configuration object that was used to generate the request.
  • statusText – {string} – HTTP status text of the response.

So you'd need to change your code to:

$http.get(dataUrl)
    .success(function (data){
        $scope.data.products = data;
    })
    .error(function (error, status){
        $scope.data.error = { message: error, status: status};
        console.log($scope.data.error.status); 
  }); 

Obviously, you don't have to create an object representing the error, you could just create separate scope properties but the same principle applies.

DoctorMick
  • 6,703
  • 28
  • 26
  • Thank you very much! Then, is the book wrong? In the book, "The object passed to the error function defines status and message properties." Is the angular changed? – nujabes Dec 16 '14 at 15:21
  • I can't see anything in the change log indicating this has changed. – DoctorMick Dec 16 '14 at 15:26
  • 1
    As of Angular 1.4 the documentation now has a deprecation notice stating "The $http legacy promise methods success and error have been deprecated. Use the standard then method instead." – Darryl Aug 06 '15 at 20:10
  • 10
    Just to reiterate @Darryl, `.success` and `.error` are now deprecated. Use `.then(function successCallback(response) {}, function errorCallback(response) {});` instead. – Defiant Feb 12 '16 at 09:27
  • `.success` and `.error` have been deprecated since this answer was posted. – James Gentes Mar 12 '16 at 03:07
10

UPDATED: As of angularjs 1.5, promise methods success and error have been deprecated. (see this answer)

from current docs:

$http.get('/someUrl', config).then(successCallback, errorCallback);
$http.post('/someUrl', data, config).then(successCallback, errorCallback);

you can use the function's other arguments like so:

error(function(data, status, headers, config) {
    console.log(data);
    console.log(status);
}

see $http docs:

// Simple GET request example :
$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });
Nitsan Baleli
  • 5,393
  • 3
  • 30
  • 52
  • Thank you very much! Then, is the book wrong? In the book, "The object passed to the error function defines status and message properties." Is the angular changed? – nujabes Dec 16 '14 at 15:19
  • I remember it the same.. make sure you always read the docs, and that they are for your version of angular. (there's a dropdown with all available versions) – Nitsan Baleli Dec 16 '14 at 15:51
7

Since $http.get returns a 'promise' with the extra convenience methods success and error (which just wrap the result of then) you should be able to use (regardless of your Angular version):

$http.get('/someUrl')
    .then(function success(response) {
        console.log('succeeded', response); // supposed to have: data, status, headers, config, statusText
    }, function error(response) {
        console.log('failed', response); // supposed to have: data, status, headers, config, statusText
    })

Not strictly an answer to the question, but if you're getting bitten by the "my version of Angular is different than the docs" issue you can always dump all of the arguments, even if you don't know the appropriate method signature:

$http.get('/someUrl')
  .success(function(data, foo, bar) {
    console.log(arguments); // includes data, status, etc including unlisted ones if present
  })
  .error(function(baz, foo, bar, idontknow) {
    console.log(arguments); // includes data, status, etc including unlisted ones if present
  });

Then, based on whatever you find, you can 'fix' the function arguments to match.

drzaus
  • 24,171
  • 16
  • 142
  • 201
6

From the official angular documentation

// Simple GET request example :
$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

As you can see first parameter for error callback is data an status is second.

Timofey
  • 141
  • 6
  • 1
    People reading this, from Angular 1.4, `.success` and `.error` has been deprecated in favor of `.then` – yorch Apr 14 '16 at 18:48
  • And from Angular 1.6, `.success` and `.error` are no longer available, you are forced to use `.then` and maybe `.catch` – jperelli Dec 28 '16 at 05:09
3

Response status comes as second parameter in callback, (from docs):

// Simple GET request example :
$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });
Rasalom
  • 3,101
  • 3
  • 21
  • 29