I have that simple code :
$http.get(\"/api/test\")
.success(function (data, status, headers, config) {
console.log(data);
return data;
I had the same problem and, honestly, follow the hints of this post put me in the wrong direction... so, I share my case/solution so other in my same situation could save time.
I'm using Angular.js 1.2.14 + WebApi 2. this my response for a NotFound status:
Cache-Control:no-cache
Content-Length:0
Date:Sat, 15 Mar 2014 14:28:35 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcU3ZpbHVwcG9EaXNjaXR1clxhcGlcTWFnMTRcYXBpXGxlc3Nvblw4NA==?=
As you can see, Content-Lenght:0, but that's ok.
My problem was the uncorrect use of Angular.js interceptor, in particular something like this:
responseError: function (result) {
// check something
return result;
}
returning result without throw an exception or rejecting the promises (as written in docs) makes Angular believe that I want to convert rejection in correct resolution and, after that, success callback is called.
I correct my code as follow:
responseError: function (result) {
// check something
return $q.reject(result);
}
We moved the post to a factory, we don't really care here about testing the $http stuff, just what it does on success or error:
factoryModule.factory('GiftFactory', function ($http, Settings) {
var saveUrl = Settings.endpoints.saveUrl;
return {
createGift: function (data) {
var gift = { gift: JSON.stringify(angular.toJson(data.gift)) };
return $http.post(saveUrl, gift);
}
};
});
We call it like this:
$scope.submit = function () {
$scope.submitting = true;
GiftFactory.createGift($scope)
.success(function () {
$window.location = Giving.endpoints.indexUrl;
}).error(function() {
$scope.submitting = false;
alert('an error occurred');
});
};
We test it like this:
describe('donation controller', function () {
var $scope, q, window, controller;
beforeEach(module('giving.donation'));
beforeEach(inject(function ($controller, $rootScope, $q) {
$scope = $rootScope.$new();
window = {};
q = $q;
giftFactory = {};
controller = $controller('DonationController', { $scope: $scope, $window: window, GiftFactory: giftFactory });
}));
describe('submit', function () {
var deferred;
beforeEach(function () {
deferred = q.defer();
deferred.promise.success = function (fn) {
deferred.promise.then(
function (response) {
fn(response.data, response.status, response.headers);
});
return deferred.promise;
};
deferred.promise.error = function (fn) {
deferred.promise.then(null,
function (response) {
fn(response.data, response.status, response.headers);
});
return deferred.promise;
};
});
it('should redirect on success', function () {
//Arrange
Giving = { endpoints: { indexUrl: "/testurl" } };
giftFactory.createGift = function () {
return deferred.promise;
};
//Act
$scope.submit();
deferred.resolve({});
$scope.$apply();
//Assert
expect($scope.submitting).toBeTruthy();
expect(window.location).toBe('/testurl');
});
it('should set submitting back to false on error', function () {
//Arrange
Giving = { endpoints: { indexUrl: "/testurl" } };
giftFactory.createGift = function () {
return deferred.promise;
};
//Act
$scope.submit();
deferred.reject({});
$scope.$apply();
//Assert
expect($scope.submitting).toBeFalsy();
expect(window.location).toBeUndefined();
});
});
});
The problem is your webserver, it is setting content-length to 0 that means that is a valid value as you can see on HTTP/1.1 specification.
Also I made a example on JSFiddle showing the error and success examples. See here.
The headers from the error example:
Request:
GET /error/ HTTP/1.1
Host: fiddle.jshell.net
Connection: keep-alive
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31
DNT: 1
Referer: http://fiddle.jshell.net/danielcsgomes/cAMc6/1/show/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: UTF-8,*;q=0.5
Cookie: csrftoken=4tNVNxC5v6BSq9yJCKkHlGFJBz3cClqd`
Response:
HTTP/1.1 404 NOT FOUND
Server: nginx/0.8.54
Date: Fri, 12 Apr 2013 00:38:07 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Cookie
Content-Encoding: gzip
If you are using AngularJS version 1.1.1 or greater...
Does appending '.json' work?:
$http.get("/api/test.json")
.success(function (data, status, headers, config) {
console.log(data);
return data;
}).error(function (data, status, headers, config) {
alert("error");
return status;
});
If so, it can also be fixed with:
myModule.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}]);
See this => Angular JS Fails After Upgrade from 1.1.0 to 1.1.1
Maybe a little on late but... At the moment Angular $http request give you a premise so you can change it to:
$http({
method: "yourMethod",
url: "yourUrl",
data: {yourDataObj}
}).then(function (res) { //first function "success"
console.log(res.data);
}, function (err) { //second function "error"
console.log(err);
});