Ajax calls return home page instead of json data

I have autocomplete and other ajax calls working fine in my local development set up but on a test server, they return the cakephp site home page instead of the json data. Could it be my apache setup?

Here’s an abbreviated example of one of my controller functions, in this case in PeopleController.php

public function search()
    {
        $this->Authorization->skipAuthorization();
        $this->autoRender = false;
        if ($this->request->is('ajax')) {
                    $people = $this->getPeopleAutocomplete($_GET['term']);
                    if ($people) {
                        sort($people);
                        $this->response = $this->response->withType('json')->withStringBody(json_encode($people));
        
                        return $this->response;
                    }
        }
}

JS autocomplete function:

export const autocompleteField = (inputFieldId, valueFieldId, url, callback) => {
    $('#' + inputFieldId).autocomplete({
        minLength: minAutocompleteLength,
        delay: 500,
        source: function (request, response) {
            $.getJSON(url, request, function (data, status, xhr) {
                if (!data) {
                    response();
                    $("#" + inputFieldId).val(ui.item.label).removeClass("ui-autocomplete-loading");
                } else {
                    response(data);
                }
            });
        },
        select: function (event, ui) {
            $("#" + valueFieldId).val(ui.item.value);
            $("#" + inputFieldId).val(ui.item.label).removeClass("ui-autocomplete-loading");
            if (callback) {
                callback();
            }
            return false;
        }
    });
}

OK, it was just that the path was different because the app is running in a subfolder.

However, is the above the recommended way to return json rather than a template?

My method of handling this is to make sure the request correctly sets the Content-Type and Accept headers to application/json, then in my controller action call:

$this->set('response', $response);
$this->viewBuilder()->setOption('serialize', 'response');

where response is the data I am returning.

See here for reference: JSON and XML views - 4.x

1 Like

You will always get an html response if you did not set autoRender off in your method.

I can see you added that.
What i can suggest is change the line
return $this->response; to echo $this->response;

And you are good.

What? No. Do not echo $this->response;. First, that’s an object, not a string. Second, even if it was a string, it’s terrible coding practice. It does not follow the standards, which exist for a good reason, it’s worse for unit testing, there’s just nothing good about it.