POST data not appearing in CakePHP controller

12,255

Solution 1

Don't encode post data as json

The code in the question won't appear in any php script, the reason is this:

contentType: "json"

It's not a form-url-encoded request, so e.g. the following code:

print_r($_POST);
print_r(file_get_contents('php://input'));

will output:

Array()
'{"customer":123}'

If you want to submit data as json, you'll need to read the raw request body:

$data = json_decode(file_get_contents('php://input'));

There might be times when that's desirable (api usage), but that isn't the normal way to use $.post.

The normal way

The normal way to submit data, is to let jQuery take care of encoding things for you:

$.ajax({  
    url: "/orders/finalize_payment",  
    type: "POST",  
    dataType: "json",  // this is optional - indicates the expected response format
    data: {"customer": customer_id},  
    success: function(){              
       alert("success");  
    }
});

This will submit the post data as application/x-www-form-urlencoded and be available as $this->request->data in the controller.

Why $.post works

I changed the request from AJAX to $.post and it worked. I still have no clue why

Implicitly with the updated code in the question you have:

  • removed the JSON.stringify call
  • changed from submitting json to submitting application/x-www-form-urlencoded

As such, it's not that $.post works and $.ajax didn't ($.post infact just calls $.ajax) - it's that the parameters for the resultant $.ajax call are correct with the syntax in the question.

Solution 2

Using raw data and json you can use:

$data = $this->request->input('json_decode');

**Data is an object now, not an array.

Then you can use:

  $this->MyModel->save($data).

Solution 3

Nicely formatted question :)

I'm pretty sure I have the answer, though I could be wrong... Basically, $this->request is an object in Cake, and $this->request->data is a variable/array that's a property of the object.

The data you're sending to Cake is going straight into the object (if this is even possible), not into the data array. This is why when Cake generates forms using the HtmlHelper, the names are, for example data[User][username].

I think, if you put JSON.stringify({"customer": customer_id}) into a 'data' array and send that, it should work.

Share:
12,255
user1104854
Author by

user1104854

Updated on June 05, 2022

Comments

  • user1104854
    user1104854 almost 2 years

    I'm using AJAX on a knockout.js form to post some information that CakePHP should receive, however, Cake doesn't seem to find anything. Also, the alert isn't appearing despite a 200 status (OK) from the POST.

    Here's the AJAX

    $.ajax({  
              url: "/orders/finalize_payment",  
              type: "POST",  
              dataType: "json",  
              contentType: "json",  
              data: JSON.stringify({"customer": customer_id}),  
              success: function(){              
                alert("success");  
              }
        }); 
    

    Here's the corresponding action in the orders controller. Right now, I completely stripped it to just the bare minimum.

    function finalize_payment($id = null){
        $this->layout = false;
        $this->autoRender = false;
        if($this->request->is('post')){ //the user has submitted which status to view
            print_r($this->request->data);
                echo "test"; //just to make sure it's reaching this point
        }
    }
    

    When I open up the network tab in chrome, it shows the request payload as

    customer: 1
    

    The POST shows as success, status 200. I checked the response headers and it just shows

    array
    (
    )
    test
    

    Despite chrome showing a payload being sent, CakePHP isn't finding it apparently.

    Update

    I changed the request from AJAX to $.post and it worked. I still have no clue why

    $.post("/orders/finalize_payment",{"customer_id":customer_id},function(data){
            alert('success');
     });