Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to output ajax data from a Magento Admin Extension

I'm writing a Magento Admin extension that has some ajax callbacks in it. Up until now I've been echoing the json I'm feeding back through the ajax call with a simple echo statement in the controller. It "works" but I get a bunch of errors like this in my log file:

 

2010-12-14T15:37:05+00:00 DEBUG (7): HEADERS ALREADY SENT:

[0] /home/simplifiedsafety/www/store/app/code/core/Mage/Core/Controller/Response/Http.php:44
[1] /home/simplifiedsafety/www/store/lib/Zend/Controller/Response/Abstract.php:727
[2] /home/simplifiedsafety/www/store/app/code/core/Mage/Core/Controller/Response/Http.php:75
[3] /home/simplifiedsafety/www/store/app/code/core/Mage/Core/Controller/Varien/Front.php:188
[4] /home/simplifiedsafety/www/store/app/code/core/Mage/Core/Model/App.php:304
[5] /home/simplifiedsafety/www/store/app/Mage.php:599
[6] /home/simplifiedsafety/www/store/index.php:104

I think to avoid this I need to push it out through some sort of block. Can someone give me a little guidance on this?

like image 540
Chris Avatar asked Dec 14 '10 16:12

Chris


2 Answers

$this->getResponse()->setBody($output)
like image 25
clockworkgeek Avatar answered Oct 23 '22 11:10

clockworkgeek


Magento uses a response object to send output back to the browser. Even when you call renderLayout from a controller, Magento is just building up the string output in memory before outputting it. The reason you're getting this error is there's system code after the controller dispatch that's attempting to set headers, but your unexpected controller output prevents those headers from being set.

The simplest solution is throw an

exit;

in directly after your controller output. This halts execution, your ajax response is sent, the world is happy. Rejoice.

Alternately, if you're looking for that always elusive "right" way, based on examples in the core, it looks like you can call the following from your controller to retrieve the response object, and then set its body directly.

$this->getResponse()->setBody('Some Response');

If you do the above, you're bypassing the Magento layout system and setting output directly, but keeping the responsibility of sending the output with the response object.

You may want to set your own values for headers (JSON, XML, etc), which you can do with something like the following (again, from a controller action)

$this->getResponse()
->clearHeaders()
->setHeader('Content-Type', 'text/xml')
->setBody('Some Response');

Good luck!

like image 199
Alan Storm Avatar answered Oct 23 '22 10:10

Alan Storm