Enrique
Enrique

Reputation: 4833

Bool parameter from jQuery Ajax received as literal string "false"/"true" in PHP

This question is related with:

Cannot pass null to server using jQuery AJAX. Value received at the server is the string "null"

But I'm asking it again because the solution in that question is very ugly, and I think must be a better one.

PROBLEM
When you send data with jQuery Ajax to PHP using POST you get strings "false"(string) instead of false(bool), "true" instead of true(bool) and "null" instead of NULL:

SOLUTION
(proposed in the above question): convert the data to JSON before send it with jQuery, and then decode that data in PHP. With code:

Javascript code:

$.ajax
(
   {
      url     : <server_url>,
      dataType: 'json',
      type    : 'POST',
      success : receiveAjaxMessage,
      data    : JSON.stringify
      (
         {
            valueTrue : true,
            valueFalse: false,
            valueNull : null
         }
      )
   }
);

PHP code:

var_dump(json_decode(file_get_contents('php://input'), true));

To me that's not a solution, only an ugly hack.

The problem in my situation is that I can't use file_get_contents('php://input') to access the $_POST, even more, I can't use $_POST because I'm using HMVC.

And I know I can fix it checking those "false", "true" and "null" in PHP, or sending 1 and 0 instear true and false in jQuery.
But I think this must be a really common problem, and jQuery is a really common framework, so I'm pretty sure there's a better and elegant way to send the data with the right type in jQuery.

Upvotes: 43

Views: 51013

Answers (5)

Quaternion
Quaternion

Reputation: 10458

If you will not handle the type conversion on the server then you must send what you expect.

Instead of:

     {
        valueTrue : true,
        valueFalse: false,
        valueNull : null
     }

Use:

     {
        valueTrue : 'TRUE',
        valueFalse: 'FALSE',
        valueNull : 'NULL'
     }

A ternary operator is pretty clear...

 valueTrue: (myvar ? 'TRUE' : 'FALSE')

But probably clearer is to append ".toString().toUpperCase()" to the variables :

 valueTrue : myvar.toString().toUpperCase();

However that will not work if myvar is null...

This example shows a converter function you can use before sending data.

<html>
    <head>
        <script>
            function myConverter(toUpper){
                if (toUpper != null){
                   return toUpper.toString().toUpperCase(); 
                }
                return 'NULL';
            }
            //tests
            alert(myConverter(null));
            alert(myConverter(true));
            alert(myConverter(false));
        </script>
    </head>
    <body>
    </body>
</html>

Upvotes: 0

loakesh bachhu
loakesh bachhu

Reputation: 381

I tried using Boolean object instead of primitive boolean type in the model at controller and it worked.

I have contentType : 'application/json; charset=utf-8' and data type as "POST".

Upvotes: 0

codelove
codelove

Reputation: 2016

Because HTTP is a text protocol with no concept of booleans or integers everything must be stringified. Comparing strings on the server side is the normal way to deal with booleans.

If you really really want PHP to see a 0 or 1 you can use

 valueTrue : true ? 1 : 0

in your AJAX call.

Upvotes: 19

skinneejoe
skinneejoe

Reputation: 3991

In my experience if you have

dataType: 'json'

and

contentType: 'application/json'

in your jQuery ajax call, and JSON.stringify your data before you send it will arrive at the server as a parse-able javascript object. Or in my case I'm using NodeJS serverside and it arrives as a Javascript object, with correct booleans, not string bools. But if I leave out the content type attribute then things get all goofed up including the bools.

Upvotes: 54

Ariel
Ariel

Reputation: 26753

I ran into the same issue. I solved it by sending a 1 or 0 for booleans.

In the $.ajax I did data : {field_name: field ? 1 : 0}

Upvotes: 5

Related Questions