livewire: groupBy and Method Illuminate\Database\Eloquent\Collection::getKey does not exist
Description
When binding the value of an Eloquent groupBy method into a Livewire component, you receive the following error. Method Illuminate\Database\Eloquent\Collection::getKey does not exist.
The same code works fine when used in a non-livewire component, such as a component or view composer.
Steps to reproduce
- Create a livewire component
- In the
mountmethod, try bind a property toUser::all()->groupBy('created_at');
Context
- Livewire version: [e.g. 11.0]
- Laravel version: [e.g. 7.0.0]
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 19 (5 by maintainers)
I can confirm this is still not working. My temporary solution is to wrap it with
collect()which is an instance ofIlluminate\Support\Collectioninstead ofIlluminate\Database\Eloquent\Collectioncollect(Permission::all()->groupBy('group'))Livewire doesn’t support using
groupByon eloquent collections.The reason for that is, they way Livewire dehydrates and rehydrates eloquent collections, is by getting all of the keys of the items in the collection, and sending them to the front end (but not the rest of the data).
When it the eloquent collection is restored on the next request, those keys are used to get the records from the database, rehydrating the eloquent collection with all the records it had before.
But when you do a groupBy, Livewire can’t serialise the eloquent collection, as it can’t call
getKeyon each of the items asgroupByputs them into nested collections (hence the error that is being displayed).Livewire has no way of knowing how the collection has been grouped.
To work around this, you could use computed properties, so lets say we have a list of users that we want grouped by name, first just get all the users and assign the standard eloquent collection to a public property
Then you could have a computed property
$this->usersByNameand use this in your blade viewHope this helps!
Another valid option is to use the
toBasemethod. Example:@marky291 yep, but computed properties don’t get serialised, so you won’t run into that issue.
Instead the computer property will compute the group by when it gets used in your blade view. But all the data is still serialised using the non-grouped public users property (as it doesn’t touch the users property, just uses it).
Computed properties also get memoized within a request too, so it will only compute it the first time it gets called (within a single request that is).
In your blade view, you would use the computed property, not the public property, so something like this
Hope that make sense 🙂
I have the same error. I fix it by having an array value instead of collection after grouping.
I think the issue here is the casting of data.
Issue still exists when we use collection that has groupBy applied.