I have set up REST for my CakePHP and I’m having a slight problem. When calling a GET method, like view or index on my controller, or even a custom method that is GET I have no problem getting an answer. But when I try to do a POST action like add I get no output from the operation even though I can see that it reached it correctly and executed (saved to the DB).
I have properly set up the layout file for JSON and XML output as well as the routing and the view for each output type.
EDIT:
Relevant code in beforeFilter in AppController:
if ( $this->RequestHandler->isAjax() ) {
$this->layout = 'ajax';
$this->autoRender = false;
} elseif ($this->RequestHandler->isXml()) {
$this->layout = 'default';
$this->RequestHandler->respondAs('xml');
$this->RequestHandler->renderAs($this, 'xml');
} elseif ($this->RequestHandler->ext == 'json') {
$this->layout = 'default';
$this->RequestHandler->respondAs('json');
$this->RequestHandler->renderAs($this, 'json');
} elseif ($this->RequestHandler->accepts('html')) {
$this->layout = 'frontend';
}
Code in Routes:
Router::mapResources('fonykers');
Router::mapResources('voicenotes');
Router::parseExtensions();
Relevant code in my add method in FonykersController:
$response = array('ok' => true, 'title' => 'Thank you for registering', 'msg' => 'A confirmation email has been sent to the provided email address, please click on the link in the email to complete the registration process');
if ($this->RequestHandler->isXml()) {
$this->set(compact('response'));
} else if ($this->RequestHandler->ext == 'json') {
pr('This prints');
$this->set(compact('response')); //View not being outputted
pr('This also prints');
} else {
echo json_encode($response);
}
My view in /views/fonykers/json
<?php echo json_encode(array('response' => $response)); ?>
My layout file for json:
<?php
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate");
header('Content-Type: application/json');
header("X-JSON: ".$content_for_layout);
echo $content_for_layout;
?>
You have a few things going on…
Your beforeFilter checks for isAjax and then uses
elseifto test for XML or JSON. If your request is AJAX, it will never get to the XML/JSON tests. Your layout is likely not being set at all which leaves you with just$this->autoRender = false;.Since autoRender is disabled, at some point you’ll have to manually invoke rendering. Using
$this->set()just prepares variables for usage in your view – it doesn’t actually output the view. In your controller action, the only line that would actually output anything isecho json_encode($response);.Use
$this->render()to force Cake to render the view when you want it to. More info in The 1.3 Book: Rendering a specific viewAs an aside, sometimes you use
...}elseif(...and sometimes you use...}else if(.... This isn’t technically wrong, but being consistent will make your code easier to read.