Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js $http.post TypeError: Cannot read property 'data' of undefined

Angular.js v1.0.6

When making an $http.post and receiving a non 200 resposne (401 in this case)

$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 throws the following error:

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)  

And never calls the either the .success() callback or .error() errback making it impossible to handle the response.

Am I doing something wrong? The success call back gets called as expected on provision of legit credentials.

200 response:

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"   } } 

401 response:

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"     }   ] } 

Further, if I adopt the normal promise syntax in favour of the .success() shortcuts I get some interesting behaviour:

$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'); }); 
like image 400
Matt Richards Avatar asked May 16 '13 14:05

Matt Richards


1 Answers

Finally got to the bottom of this. The problem was due to the following global HTTP interceptor implementation:

'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 } 

FIX:

if (status === 401) {   $rootScope.$broadcast('event:loginRequired'); } 
like image 160
Matt Richards Avatar answered Sep 28 '22 08:09

Matt Richards