Sending JSON using $http cause angular to send text/plain content type
Asked Answered
L

2

6

I just want to send the following JSONobjects to my API backend:

{
    "username":"alex",
    "password":"password"
}

So I wrote the following function, using Angular $http:

$http(
{
    method: 'POST', 
    url: '/api/user/auth/',
    data: '{"username":"alex", "password":"alex"}',
})
.success(function(data, status, headers, config) {
 // Do Stuff
})
.error(function(data, status, headers, config) {
 // Do Stuff
});

I read in documentation for POST method that Content-Type header will be automatically set to "application/json".

But I realized that the content-type I receive on my backend (Django+Tastypie) api is "text/plain".

This cause my API to not respond properly to this request. How should I manage this content-type?

Lithograph answered 30/8, 2013 at 8:14 Comment(5)
How your backend is retrieving the details?Transition
I use Django Tastypie for my Backend. I see text/plain in content type sending by $http. raw_post_data or POST data is also empty.Lithograph
So strange... If I put headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'} it is working.. But if I put application/json... it's not...Lithograph
I'm also seeing this behavior. When the data block is empty it seems that Angular is ignoring the default "application/json" and setting the Content-Type to "plain/text". Neither explicitly setting the default on $http nor setting the Content-Type as an argument to the put() call seems to have any effect. I am using AngularJS 1.2.0.Kenaz
Are you setting headers through configuration phase?Endblown
K
2

The solution I've moved forward with is to always initialize models on the $scope to an empty block {} on each controller. This guarantees that if no data is bound to that model then you will still have an empty block to pass to your $http.put or $http.post method.

myapp.controller("AccountController", function($scope) {
    $scope.user = {}; // Guarantee $scope.user will be defined if nothing is bound to it

    $scope.saveAccount = function() {
        users.current.put($scope.user, function(response) {
            $scope.success.push("Update successful!");
        }, function(response) {
            $scope.errors.push("An error occurred when saving!");
        });
    };
}

myapp.factory("users", function($http) {
    return {
        current: {
            put: function(data, success, error) {
                return $http.put("/users/current", data).then(function(response) {
                    success(response);
                }, function(response) {
                    error(response);
                });
            }
        }
    };
});

Another alternative is to use the binary || operator on data when calling $http.put or $http.post to make sure a defined argument is supplied:

$http.put("/users/current", data || {}).then(/* ... */);
Kenaz answered 13/11, 2013 at 20:46 Comment(0)
T
0

Try this;

$http.defaults.headers.post["Content-Type"] = "application/json";

$http.post('/api/user/auth/', data).success(function(data, status, headers, config) {
 // Do Stuff
})
.error(function(data, status, headers, config) {
 // Do Stuff
});
Transition answered 30/8, 2013 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.