Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Eloquent toArray not using square braces

I'm writing an api and attempting to convert a number of results into JSON. When the eloquent result is converted to an array, I am expecting something like this:

[
  {
     "id": "0", ...
  }, 
  {
     "id": "", ...
  }, 
]

but instead, Laravel displays it as a key, value list using the table key:

"0":{
       {
          "id": "0", ...
       }
    },
"1":{
       {
          "id": "1", ...
       }
    }

Here is the function:

$results = \App\Event::with('sandboxes')->get()->sortBy('start_time')->forPage($pageNum,$perPage);
    return response()->json(array(
        "events" => $page,
    ));

How can I get Laravel to give me a proper array?

like image 915
Deal Seal Avatar asked Mar 26 '16 02:03

Deal Seal


1 Answers

When you first get your events, your Collection looks something like this:

[
    0 => Event1,
    1 => Event2,
    2 => Event3
]

This is a properly indexed numeric array, and can be represented as an array in JSON. However, once you get your Collection, you call sortBy() on it, which sorts the items in the Collection. This sorting rearranges both the keys and the values of the items inside the array. At this point, your Collection may look something like:

[
    1 => Event2,
    0 => Event1,
    2 => Event3
]

This is not a properly indexed numeric array, and cannot be represented as an array in JSON. This array must be represented as an object, which is what you are seeing.

In order to get the results you're expecting, you need to re-key the items in the Collection after you sort it. You can do this with the values() method on the Collection (which just calls array_values() on the internal items array).

Once you re-key your Collection, it will look something like:

[
    0 => Event2,
    1 => Event1,
    2 => Event3
]

This is now a properly indexed numeric array and can be represented as an array in JSON.

So, your code should look something like:

$results = \App\Event::with('sandboxes')
    ->get()
    ->sortBy('start_time')
    ->values() // re-key the items in the collection after sorting
    ->forPage($pageNum, $perPage);
like image 197
patricus Avatar answered Sep 21 '22 22:09

patricus