Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joomla - Controller task that returns JSON data

I have the task run in my controller. I want it to return JSON data. As it stands, I am getting my JSON data wrapped inside the template HTML. How do I tell Joomla to just return JSON data from the controller? This is the function I have:

public function run  ( ) {

    JFactory::getDocument()->setMimeEncoding( 'application/json' );

    JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');

    JRequest::setVar('tmpl','component');

    $data = array(
        'foo' => 'bar'
    );

    echo json_encode( $data );

}

And this returns:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" dir="ltr">
...
</head>
<body class="contentpane">

<div id="system-message-container">
</div>
    {"foo":"bar"}
</body>
</html>

I would like to get:

{"foo":"bar"}
like image 914
Jeffrey Ray Avatar asked May 24 '13 16:05

Jeffrey Ray


2 Answers

Joomla 4

You have to add the parameter &format=json to your URL. This tells the system that you are waiting for a json response. The system will render JsonDocument and will send correct browser headers as response.

index.php?option=com_foo&task=report.run&format=json
class Report extends BaseController {

   public function run() {
       $data = [
         'foo' => 'bar'
       ];

       $response = new ResponseJson($data);

       echo $response;
   }
}

There is no need for closing the application with $app->close(); because the architecture of Joomla handles that for you.

If you close the application you will miss lot of stuff during the process of rendering. Many of the events will not be triggered. Furthermore, you will have to send headers for content type manually.

Your code should look like this one. This approach is not recommend.

class Report extends BaseController {

   public function run() {

       $this->app->mimeType = 'application/json';
       $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet);
       $this->app->sendHeaders();

       $data = [
         'foo' => 'bar'
       ];

       $response = new ResponseJson($data);

       echo $response;

       $this->app->close();
   }
}
like image 165
Todor Iliev Avatar answered Sep 28 '22 01:09

Todor Iliev


Quick method in existing controller

You need to use jexit() to return json data without any Joomla output.

public function run  ( ) {

    $data = array(
        'foo' => 'bar'
    );

    echo json_encode( $data );
    jexit();

}

Joomla 3.x Method

The better alternative is to create JSON controller and use JResponseJson to output JSON. The file name should have JSON suffix. For example, if your controller is an item, then your file name can be item.json.php and you can add controller code something like below.

public function run  ( ) {
  $data = array(
    'foo' => 'bar'
  );
  echo new JResponseJson($data);
}

The output will be json like below.

{"success":true,"message":null,"messages":null,"data":["foo": "bar"]}

Your ajax URL should have json parameter to trigger this json controller.

index.php?option=com_mycomponent&task=item.run&format=json

Use JResponseJson to inform errors and messages as well. Read complete documentation at the below location.

https://docs.joomla.org/JSON_Responses_with_JResponseJson

like image 31
Nagarjun Avatar answered Sep 28 '22 02:09

Nagarjun