Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
How to setup Hybrid controllers to return json for ajax/non-ajax calls?
  • After getting my base controller extensions setup and thinking I had everything figured out am now running into issues with trying to cleanly get json returned from an action for both AJAX style calls as well as normal browser page loads to same requested URI.

    A bit about my controller setup:

    -I have created a new base Template controller(using themes) that extends Hybrid that all of my controllers extend. I have followed style done in Fuel Depot repo example that has the following in the after() method:

            if ( ! \Input::is_ajax())
            {
                // If nothing was returned set the theme instance as the response
                if (empty($response))
                {
                    $response = \Response::forge(\Theme::instance());
                }

                if ( ! $response instanceof Response)
                {
                    $response = \Response::forge($response);
                }
                return $response;
            }
            return parent::after($response);


    Running into miss-behavior when trying to have some action methods return json.  Below is an example of how I am coding my actions that I would like to return as a REST/json type response:

            $this->format='json';

            $model_list = Model_Foo::query()->select('id','name')->where('name','LIKE',$query)->get();
            $data = array();
            foreach($model_list as $i => $model)
            {
                $data[] = $model->to_array();
            }
            return $data;

    I would like to just use the $this->format='json' in my actions where I want to returned content to be spit out json_encoded correctly.  Is this possible w/o having to set any other params/config values for each action?

  • Figured a temporary work around, changed my after() to return this if its a json format respose:

            if($this->action_format_type() == 'json')
            {
                $response = \Response::forge(json_encode($response,false));
            }
            return parent::after($response);


    That appears to be returning correct json response for both browser/GET calls as well as AJAX type ones.  One issue with work around seems to be that the content type isnt getting set correctly, still text/html by default, right now thats not a big deal.

    Will continue to poke around the Controller structures and Fuel Depot example to see if I can more properly adapt mine to support Hybrid setup with use of Themes
  • I think you should use $this->response :


    $this->format='json';

            $model_list = Model_Foo::query()->select('id','name')->where('name','LIKE',$query)->get();
            $data = array();
            foreach($model_list as $i => $model)
            {
                $data[] = $model->to_array();
            }
            $this->response( $data );
  • Problem I seem to run into is that the ->response() method isnt available.  In following the FuelDepot project as a reference, I wanted to similarly have all my controllers be hybrids, and in copying the reference I think things dont get setup correctly with the parent::before(); chain of execution.

    Seems to be issue with using Hybrid controllers by instead of views using Themes for rendering and breaking out of the parent::before() flow if not an ajax/restful call
  • HarroHarro
    Accepted Answer
    The response() method is provided by Controller_Rest, which is the parent of Controller_Hybrid. So it should be available to any controller that extends either one...
  • Thats what I thought, but think b/c in following the FuelDepot reference parent::before() isnt called on non ajax calls because it causes some errors with the theme/view handling.  Here is brief version of the before from it:

            if (\Input::is_ajax())
            {
                return parent::before();
            }

            // define the theme template to use for this page, set a default if needed
            \Theme::instance()->set_template($this->template);

    Without the parent::before() getting called the response property was never being setup on the controller in the parent::before()


  • I don't think the Depot code is fully compatible with the latest FuelPHP version...

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion