Anyone successfully use 3.x with jquery autocomplete and ajax/json?

I can’t seem to get a json object over ajax that jquery can deal with under cakephp 3.x

The autocomplete widget basically spits out the entire JSON string as at match when I try searching for a term.

I’ve successfully use autocomplete with 3.x ONLY if I preload all my data into a manually crafted json object that lives statically on the ctp page. But when I try to access the data using jquery’s source: attribute it falls apart completely. Also, if I try to use json_encode, even with a static object, it fails.

I’m not sure it means anything, but it looks the issue has something to do with how both cakephp’s auto-serialize functionality and json_encode add quotations to everything inside the array, even the object “keys” (value and label). When I make my object manually, I don’t use quotes on the keys.

I have tried and tried and tried and tried to simply create my own json object and spit it out on an empty blank page, but that doesn’t work either because cakephp somehow decides to throw my json object as a single encoded string that lives inside a larger json object.

Here’s an example of what gets returned if I use _serialize and let cake automagically translate the array into a json object over ajax:

 {
   "users": [
        {
            "value": "46",
            "label": "Test User"
        }
    ]
}
  • what I really want is the contents of “users”

otoh, if I manually build my object in the controller and use _serialize, I get this

{
    "users": "[ {value: \u002246\u0022, label: \u0022Test User\u0022} ]"
}
  1. what’s up with the \u0022?
  2. It’s still a sub-object
  3. And if I turn off serialize, my parent json object is even bigger, with “users” being the last item in it (user auth info I set in the AppContoller appears as part of the object in that case)

Finally, if I pass the array as-is to my view, and manually build my json object in the view, I still get the same thing as the first example above. Somehow, it’s still a subject even though it’s a freaking string I myself defined!!! And somehow, all my keys are quoted even though I never added the quotes.

Madness.

I remember having a similar issue, hopefully someone who understands how the _serialize key works will reply.
I suspect there’re some best practices modifications going on that are not really obvious…

In the meanwhile, I really don’t think you need to use _serialize unless you’re building an API.

Simply use die(json_encode($data)) at the end of the autocomplete action and you will very predictably get the result you expect. It’s not as flexible (well, you can make it more flexible) but there’s really no need for that if all it’s used for is internal functionality.

1 Like

Sometimes for simple stuff I just use an array

function findDog()
    {
        $this->autoRender = false;
        $dogid = $_REQUEST['id'];
        //echo $dogid;

        $dogs = TableRegistry::get('Dogs');
        $data2 = $dogs
                ->find()
                ->where(['dogid' => $dogid])
                ->first();
        $dogname = $data2->dogname;
        $dogcomment = $data2->comments;
        $data = $dogname . '|' . $dogcomment;
        echo $data;
    }

Notice pipe used as seperator "|"
Then

$("#mytable td:nth-child(1)").click(function (event)
    {
        event.preventDefault();
        var $td = $(this).closest('tr').children('td');
        var currentCellText = $td.eq(0).text();
        var CellText = $td.eq(1).text();
        $.ajax({
            url: "<?php echo DIR . 'dog/finddog';    ?>",
            type: 'GET',
            data: 'id=' + currentCellText,
            success: function (data) {
                var mystr = data.split("|");
                alert(mystr[1]);

            }
        });

    });

Just worked this up quickly as a test, but works.

I posted this same question on stackoverflow and someone pointed out that the _serialize() call had my array INSIDE another array and that if I passed my bare array to _serialize() I should get it echoed at the top level of my ajax response.

It never crossed my mind to use _serialize any other way because that’s how Bake creates it.

At first, I thought that was not the solution because even after changing it, I still had a problem and autocomplete failed.

I tried Ali’s recommendation and that worked like a charm. Ali is truly the Captain Kirk of CakePHP’s Kobayashi Maru issues.

However, later on, while cleaning up the code, removing commented debug statements, I accidentally removed the die() code, leaving the original serialize() without the array and noticed that it was working correctly.

I had noticed in earlier attempts to figure out this problem before posting here that sometimes code changes in the controller were not reflected for about a minute or so in a subsequent test. It seems as if the ajax queries/responses are being cached in some way.

Anyway. It’s working now and the solution was simply to pass the array unencapsulated to _serialize.