In angular $http service, How can I catch the "status" of error?

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?


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.


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.


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.
  });

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.