web-dev-qa-db-fra.com

Angular.js $ http.post TypeError: Impossible de lire la propriété 'data' d'undefined

Angular.js v1.0.6

Lors de la création d'un $ http.post et de la réception d'un non 200 resposne (401 dans ce cas)

$http.post('http://localhost:3030/auth/login', {
  username: 'username',
  password: 'password'
})
.success(function(data) {
  // Gets called on a 200 response, but not on a 401
  console.log('success');
})
.error(function(err) {
  // Never gets called & dies with error described below.
  console.log('error');
});

Angular renvoie l'erreur suivante:

TypeError: Cannot read property 'data' of undefined
    at http://localhost:9000/components/angular/angular.js:8891:22
    at wrappedCallback (http://localhost:9000/components/angular/angular.js:6797:59)
    at http://localhost:9000/components/angular/angular.js:6834:26
    at Object.Scope.$eval (http://localhost:9000/components/angular/angular.js:8011:28)
    at Object.Scope.$digest (http://localhost:9000/components/angular/angular.js:7876:25)
    at Object.Scope.$apply (http://localhost:9000/components/angular/angular.js:8097:24)
    at done (http://localhost:9000/components/angular/angular.js:9111:20)
    at completeRequest (http://localhost:9000/components/angular/angular.js:9274:7)
    at XMLHttpRequest.xhr.onreadystatechange (http://localhost:9000/components/angular/angular.js:9244:11) 

Et n'appelle jamais le callback .success() ou .error() ce qui rend impossible de gérer la réponse.

Est-ce que je fais quelque chose de mal? Le rappel de succès est appelé comme prévu sur la fourniture d'informations d'identification légitimes.

Réponse 200:

Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Auth-Token
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:99
Content-Type:application/json
Date:Thu, 16 May 2013 13:57:51 GMT

{
  "auth-token":"676932cc1e183a64334345944ad432d1908f8110bc",
  "user": {
    "id":1,
    "username":"username"
  }
}

Réponse 401:

Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Auth-Token
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:45
Content-Type:application/json
Date:Thu, 16 May 2013 13:58:25 GMT

{
  "error": [
    {
      "message":"Invalid Credentials"
    }
  ]
}

De plus, si j'adopte la syntaxe de promesse normale en faveur des raccourcis .success (), j'obtiens un comportement intéressant:

$http.post('http://localhost:3030/auth/login', {
  username: username,
  password: password
}).then(function (resp) {
  // On a 200 response, resp is a response object.
  // On a 401 response, resp is undefined.
  console.log(resp);
}, function() {
  console.log('error');
});
27
Matt Richards

Enfin arrivé au fond de cela. Le problème était dû à l'implémentation d'intercepteur HTTP globale suivante:

'use strict';
// register the interceptor as a service
angular.module('imvgm')
  .factory('httpInterceptor', ['$q', '$rootScope',  function($q, $rootScope) {

  function success(response) {
    return response;
  }

  function error(response) {
    var status = response.status;

    if (status === 401) {
      $rootScope.$broadcast('event:loginRequired');
      return
    }
    // otherwise
    return $q.reject(response);
  }

  return function(promise) {
    return promise.then(success, error);
  };

}]);

N.B

if (status === 401) {
  $rootScope.$broadcast('event:loginRequired');
  return // Returns nothing
}

RÉPARER:

if (status === 401) {
  $rootScope.$broadcast('event:loginRequired');
}
41
Matt Richards