AngularJS HTTP post to PHP and undefined

PhpJavascriptAngularjs

Php Problem Overview


I have a form with the tag ng-submit="login()

The function gets called fine in javascript.

function LoginForm($scope, $http)
{
	$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

	$scope.email 	= "[email protected]";
	$scope.password = "1234";

	$scope.login = function()
	{
		data = {
			'email' : $scope.email,
			'password' : $scope.password
		};

		$http.post('resources/curl.php', data)
		.success(function(data, status, headers, config)
		{
			console.log(status + ' - ' + data);
		})
		.error(function(data, status, headers, config)
		{
			console.log('error');
		});
	}
}

I am getting a 200 OK response back from the PHP file, however, the returned data is saying that email and password are undefined. This is all the php I have

<?php
$email = $_POST['email'];
$pass  = $_POST['password'];
echo $email;
?>

Any idea why I am getting undefined POST values?

EDIT

I wanted to point out since this seems to be a popular question (yet it is old), .success and .error have been deprecated and you should use .then as @James Gentes pointed out in the commments

Php Solutions


Solution 1 - Php

angularjs .post() defaults the Content-type header to application/json. You are overriding this to pass form-encoded data, however you are not changing your data value to pass an appropriate query string, so PHP is not populating $_POST as you expect.

My suggestion would be to just use the default angularjs setting of application/json as header, read the raw input in PHP, and then deserialize the JSON.

That can be achieved in PHP like this:

$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$email = $request->email;
$pass = $request->password;

Alternately, if you are heavily relying on $_POST functionality, you can form a query string like [email protected]&password=somepassword and send that as data. Make sure that this query string is URL encoded. If manually built (as opposed to using something like jQuery.serialize()), Javascript's encodeURIComponent() should do the trick for you.

Solution 2 - Php

I do it on the server side, at the begining of my init file, works like a charm and you don't have to do anything in angular or existing php code:

if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST))
    $_POST = json_decode(file_get_contents('php://input'), true);

Solution 3 - Php

In the API I am developing I have a base controller and inside its __construct() method I have the following:

if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
    $_POST = array_merge($_POST, (array) json_decode(trim(file_get_contents('php://input')), true));
}

This allows me to simply reference the json data as $_POST["var"] when needed. Works great.

That way if an authenticated user connects with a library such a jQuery that sends post data with a default of Content-Type: application/x-www-form-urlencoded or Content-Type: application/json the API will respond without error and will make the API a little more developer friendly.

Hope this helps.

Solution 4 - Php

Because PHP does not natively accept JSON 'application/json' One approach is to update your headers and parameters from angular so that your api can use the data directly.

First, Parameterize your data:

data: $.param({ "foo": $scope.fooValue })

Then, add the following to your $http

 headers: {
     'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
 },	

If all of your requests are going to PHP the parameters can be set globaly in the configuration as follows:

myApp.config(function($httpProvider) {
	$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});

Solution 5 - Php

Angular Js Demo Code :-

angular.module('ModuleName',[]).controller('main', ['$http', function($http){
                
                var formData = { password: 'test pwd', email : 'test email' };
                var postData = 'myData='+JSON.stringify(formData);
                $http({
                        method : 'POST',
                        url : 'resources/curl.php',
                        data: postData,
                        headers : {'Content-Type': 'application/x-www-form-urlencoded'}  
                            
                }).success(function(res){
                        console.log(res);
                }).error(function(error){
                        console.log(error);
		});
                
        }]);

Server Side Code :-

<?php


// it will print whole json string, which you access after json_decocde in php
$myData = json_decode($_POST['myData']);
print_r($myData);
 
?>

Due to angular behaviour there is no direct method for normal post behaviour at PHP server, so you have to manage it in json objects.

Solution 6 - Php

You need to deserialize your form data before passing it as the second parameter to .post (). You can achieve this using jQuery's $.param (data) method. Then you will be able to on server side to reference it like $.POST ['email'];

Solution 7 - Php

This is the best solution (IMO) as it requires no jQuery and no JSON decode:

Source: https://wordpress.stackexchange.com/a/179373 and: https://stackoverflow.com/a/1714899/196507

Summary:

//Replacement of jQuery.param
var serialize = function(obj, prefix) {
  var str = [];
  for(var p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.push(typeof v == "object" ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
};

//Your AngularJS application:
var app = angular.module('foo', []);

app.config(function ($httpProvider) {
    // send all requests payload as query string
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return serialize(data);
    };

    // set all post requests content type
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});

Example:

...
   var data = { id: 'some_id', name : 'some_name' };
   $http.post(my_php_url,data).success(function(data){
        // It works!
   }).error(function() {
        // :(
   });

PHP code:

<?php
    $id = $_POST["id"];
?>

Solution 8 - Php

It's an old question but it worth to mention that in Angular 1.4 $httpParamSerializer is added and when using $http.post, if we use $httpParamSerializer(params) to pass the parameters, everything works like a regular post request and no JSON deserializing is needed on server side.

https://docs.angularjs.org/api/ng/service/$httpParamSerializer

Solution 9 - Php

It took me hours to understand that while working with Angular and PHP. Post data was not going to PHP in $_POST

in PHP code do the following.

  • Create a variable $angular_post_params
  • Then do the following $angular_http_params = (array)json_decode(trim(file_get_contents('php://input')));

now you can access your parameters like you do from $_POST

$angular_http_params["key"]

in case you were wondering about javascript....this is what i used

    var myApp = angular.module('appUsers', []);
    //var post_params = $.param({ request_type: "getListOfUsersWithRolesInfo" });
    var dataObj = {
        task_to_perform: 'getListOfUsersWithRolesInfo'
    };

    myApp.controller('ctrlListOfUsers', function ($scope, $http) {
        $http({
            method: 'POST',
            dataType: 'json',
            url: ajax_processor_url,
            headers: {
                'Content-Type': 'application/json'
            },
            data: dataObj,
            //transformRequest: function(){},
            timeout: 30000,
            cache: false
        }).
        success(function (rsp) {
            console.log("success");
            console.log(rsp);
        }).
        error(function (rsp) {
            console.log("error");
        });
    });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRonnieView Question on Stackoverflow
Solution 1 - PhpMike BrantView Answer on Stackoverflow
Solution 2 - PhpvalmarvView Answer on Stackoverflow
Solution 3 - PhpTim WickstromView Answer on Stackoverflow
Solution 4 - PhpMalkusView Answer on Stackoverflow
Solution 5 - PhpRajendra KhabiyaView Answer on Stackoverflow
Solution 6 - PhpbahramzyView Answer on Stackoverflow
Solution 7 - PhplepeView Answer on Stackoverflow
Solution 8 - PhpDinaView Answer on Stackoverflow
Solution 9 - PhpTalhaView Answer on Stackoverflow