Reputation: 2167
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');
});
Upvotes: 11
Views: 12920
Reputation: 49
Use print_r($this->request->params);
function finalize_payment($id = null){
$this->layout = false;
$this->autoRender = false;
if($this->request->is('post')){ view
print_r($this->request->params);
} }
Upvotes: 0
Reputation: 6054
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).
Upvotes: 2
Reputation:
As you're using CakePHP you may find adding RequestHandler to your components fixes the problem.
public $components = array([snip], 'RequestHandler');
Doing this allowed me to transparently access JSON posted data using $this->request->data. The other answer's advice to not encode POST data as JSON becomes a bit awkward, given that certain JS frameworks, such as Angular, post JSON as default.
Upvotes: 2
Reputation: 66378
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 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.
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:
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.
Upvotes: 18
Reputation: 1330
Have a look at this post. You're data string probably isn't correct. Therefore CakePHP might not be able to put it in $this->request->data
.
Upvotes: 0
Reputation: 12701
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.
Upvotes: 1