Rectangle 27 0

AngularJs $http.post() does not send data?


var app = angular.module('my_app', [ ... , 'httpPostFix']);
  • Download it as an AngularJS module from here,
Note
Rectangle 27 0

AngularJs $http.post() does not send data?


$http({
    method: 'POST',
    url: 'request-url',
    data: $httpParamSerializerJQLike(json-form-data),
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
    }
});

$httpParamSerializerJQLike is angular's in-built service which serializes json in the same way $.param does of jQuery.

But you can modify angular $http service's default behavior by

It's not angular's fault. Angular is designed to work in JSON world. So when $http service send AJAX request, it send all your data as a payload, not as form-data so that your backend application can handle it. But jQuery does some things internally. You instruct jQuery's $ajax module to bind form-data as JSON but before sending AJAX request, it serialized JSON and add application/x-www-form-urlencoded header. This way your backend application able to received form-data in form of post parameters and not JSON.

when I tried with, $http.put('/api/', {name:1}). it's sending with serialized json data. but for POST, I need to set header and serialize the data as you said. do you know why PUT doesn't need that, but only POST need?

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


// Your app's root module...
angular.module('MyModule', [], function($httpProvider) {
  // Use x-www-form-urlencoded Content-Type
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';

  /**
   * The workhorse; converts an object to x-www-form-urlencoded serialization.
   * @param {Object} obj
   * @return {String}
   */ 
  var param = function(obj) {
    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

    for(name in obj) {
      value = obj[name];

      if(value instanceof Array) {
        for(i=0; i<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }

    return query.length ? query.substr(0, query.length - 1) : query;
  };

  // Override $http service's default transformRequest
  $httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
  }];
});
Content-Type: application/json
Content-Type: x-www-form-urlencoded
bower install angular-post-fix --save-dev
{ "foo": "bar", "baz": "moe" }

Amazing. I faced a lot of problem but this solved it. :)

I had the same problem using asp.net MVC and found the solution here

The difference is in how jQuery and AngularJS serialize and transmit the data. Fundamentally, the problem lies with your server language of choice being unable to understand AngularJSs transmission natively ... By default, jQuery transmits data using

There is much confusion among newcomers to AngularJS as to why the $http service shorthand functions ($http.post(), etc.) dont appear to be swappable with the jQuery equivalents (jQuery.post(), etc.)

This code works great on the most part, but I've had issues with it when submitting a hierarchy of empty objects or even flat empty values. For example, { a: 1, b: { c: { d: { } } }, e: undefined, f: null, g: 2 } will not be encoded properly, and PHP will get it as [ "a" => "1", "g" => "2" ]. The entire structure under "b", as well as "e" and "f", including the keys themselves - would be lost. I posted alternative code below, with which the above structure gets decoded as: [ "a" => "1", "b" => [ "c" => [ "d" => "" ] ], "e" => "", "f" => "", "g" => "2" ].

Works like a charm.

and the familiar foo=bar&baz=moe serialization.

so is there a way to change php's transmits data method. Because that is the issue I am having currently.

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


@Zalaboza, I would agree that it is tough to have any solution considered 'universal' but I don't agree that it is 'hacky'--- php.net states: "file_get_contents() is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance." Granted we're not reading a file in this situation but we are nonetheless reading posted json data. It would be great if you could contribute a new answer or provide new information to help readers (including myself) make a better decision about this.

I needed to add true to force it to an array when overwriting the $_POST array with it. json_decode(file_get_contents('php://input'), true);

hacky, should not be used as a universal solution

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


var xsrf = $.param({fkey: "key"});
$http({
    method: 'POST',
    url: url,
    data: xsrf,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

I have had a similar issue, and I wonder if this can be useful as well: https://stackoverflow.com/a/11443066

It looks like the headers was the only change we needed. Thank you!

Thanks, that did it for me :) The problem was the encoding of the POST data.

Thanks, this worked (and is nicest solution of this page!)

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


myobject = {'one':'1','two':'2','three':'3'}

Object.toparams = function ObjecttoParams(obj) {
    var p = [];
    for (var key in obj) {
        p.push(key + '=' + encodeURIComponent(obj[key]));
    }
    return p.join('&');
};

$http({
    method: 'POST',
    url: url,
    data: Object.toparams(myobject),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

Simplest solution in my opinion!

Worked like a charm.. +1

the function ObjecttoParams works like charm ! Thanks a lot.

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


$scope.SendData = function () {
           // use $.param jQuery function to serialize data from JSON 
            var data = $.param({
                fName: $scope.firstName,
                lName: $scope.lastName
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/ServerRequest/PostDataResponse', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
            })
            .error(function (data, status, header, config) {
                $scope.ResponseDetails = "Data: " + data +
                    "<hr />status: " + status +
                    "<hr />headers: " + header +
                    "<hr />config: " + config;
            });
        };

Didn't find a complete code snippet of how to use $http.post method to send data to the server and why it was not working in this case.

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
data
function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}

It doesn't seem to work. I've just tried the variation with the data as string and : headers: {'Content-Type': 'application/x-www-form-urlencoded'} - and that seem to work, but is there a better way of doing it?

Set default content type as described above and for data don't use js object. Use string like this: 'message='+message Works for me

The $http.post and $http.put methods accept any JavaScript object (or a string) value as their data parameter. If data is a JavaScript object it will be, by default, converted to a JSON string.

You can set the default "Content-Type" like this:

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


data: "message=" + message
data: $.param({message:message})

To send data via Post methode with $http of angularjs you need to change

Note
Rectangle 27 0

AngularJs $http.post() does not send data?


app.use(bodyParser.json());

I had the same problem in express .. to resolve you have to use bodyparser to parse json objects before sending http requests ..

Note