Livewire does not respect the order of array

I have an array and trying to pass it to the view.

$products = Product::orderBy('sort_order')->get()->keyBy('id')->toArray();

That returns in php

$products = [
     2 => [
           "id"=2,
           "title"="Product2",
           "sort_order"=1,
     ],
     1 => [
           "id"=1,
           "title"="Product1",
           "sort_order"=2,
     ]
]

However in blade the order of the array is displayed as:

$products = [
     1 => [
           "id"=1,
           "title"="Product1",
           "sort_order"=2,
     ],
     2 => [
           "id"=2,
           "title"="Product2",
           "sort_order"=1,
     ]
]

How can I tackle this?

Hey, @aspyropoulos

The order has nothing to do with livewire, this is laravel thing (eloquent).

You can pass the 2nd param into OrderBy() method and define the order asc or desc

orderBy('sort_order', 'asc'); // default "desc"

Thanks for the update. I removed the ->keyBy(‘id’) and it worked. The question is how I can make it work by using ->keyBy(‘id’) also.

No, the title here is correct and it’s an annoying Livewire problem. It seems to assume any array with integers as keys is an indexed array and will reorder and rekey them from 0 on the server round trips.

Without changing your design pattern, a semi-hacky fix I came up with was to convert it to an associative array, changing the keys from 0,1,2 to product0, product1, product2 and then livewire won’t reorder or rekey it. Then a simple $id = (int) Str::after($key, 'product'); to get the original back when you need to use it.

2 Likes