Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel grouped collection returns object instead of array

I have the following query

$outings = Outing::all()->groupBy(function ($item) {
   return Carbon::parse($item['start'])->format('m/d/Y');
});

return response()->json([
    'outings' => $outings
], 200);

The response is returning an object and I need it to return an array As you can see, outings is an object and not an array

How can I get outings to be an array instead of an object.

If I don't group the collection and just do

Outing::all();

It will return an array rather than an object. The Group by is doing something weird.

If I DD($outings) it does in fact return a collection, so I think it's odd that it gets cast to an object when returned to the browser rather than an array.

Below is the output when I DD($outings->toArray())

enter image description here

Thanks

like image 329
Kyle Reierson Avatar asked Jun 28 '18 15:06

Kyle Reierson


3 Answers

Use array_values($array) to force an associative array into a JSON array. You will lose any key names this way, however.

$outings = Outing::all()->groupBy(function ($item) {
   return Carbon::parse($item['start'])->format('m/d/Y');
});

return response()->json([
    'outings' => array_values($outings)
], 200);

No one has really explained why this happens.

In JavaScript/JSON, arrays are just collections of values, they are keyed but the key is always numerical in sequence.

In PHP, arrays are collections of "key" => "value" pairs, the key can be anything (integer or string) but arrays can generally be considered "associative" (where the key is non-numerical, or numerical but not in sequence) or "non-associative" (where the key is numerical AND in sequence (similar to JS arrays).

When it comes to encoding a PHP array as JSON, say an array has keys that are non-numeric OR the keys are numeric but not in sequential order (e.g. 0, 1, 2, 4, 5, 8, 10) - these types of arrays are not compatible with JavaScript/JSON arrays. In this case, the array is converted into an object to preserve the keys. To force the array to be converted into an array, you must convert the array into a non-associative array (numerical sequenced keys), PHP has the function array_values to help with this.

like image 176
Turbotailz Avatar answered Nov 03 '22 02:11

Turbotailz


Use ->values()

$outings = Outing::all()->groupBy(function ($item) {
   return Carbon::parse($item['start'])->format('m/d/Y');
});

return response()->json([
    'outings' => $outings->values()
], 200);
like image 6
mikoop Avatar answered Nov 03 '22 03:11

mikoop


If you want array then use this

$outings = Outing::all()->groupBy(function ($item) {
   return Carbon::parse($item['start'])->format('m/d/Y');
})->map(function($item){
    return $item->all();
});

return response()->json($outings, 200);

If you want date as key then

$outings = Outing::all()->groupBy(function ($item) {
   return Carbon::parse($item['start'])->format('m/d/Y');
});

return response()->json($outings->toArray(), 200);
like image 5
rkj Avatar answered Nov 03 '22 02:11

rkj