Custom Field disappear after LiveWire update
One dev in my team created a
PracticeMatrix
custom field.
Everything was working fine until I added ->live(onBlur: true)->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))),
to a TextField to automatically generate a Slug in TextInput::make('slug')
.
Now, when I blur
the TextField
, most of the BestPracticeMatrix
component disappear and I don't know why.
The controller or the blade view are probably not correct, but I'm not familiar with LiveWire and filamentphp custom field.
I can't seem to find documentation on how to do custom field.
Does anybody knows why the field disappear ?
What I know so far is when the blur happen, LireWire update the page and the $practicesData = $getPracticesData();
is now an empty array so the @foreach
in the template is not rendering anything.
Here is the code: https://gist.github.com/mrleblanc101/f05af5990556f92d8f983c8184dff089Solution:Jump to solution
I guess so, first time using filament and livewire, and this code wasn't from me.
But it kinda feels wonky to call PHP methods from the template 😬
Seems like it should be in the Controller and passed down, but that's where it reset the array when LireWire update.
But i'm very unfamillar with how to pass data from the Controller to the field, there is basically zero documentation about that. Only how to do a very basic
ViewField::make()
...28 Replies
The table rows need keys
wire:key
?I've cleaned it up a little, but adding a
wire:key
to <x-filament-tables::row>
doesn't seem to change anything: https://gist.github.com/mrleblanc101/a88deb517a594ed9adfadc1c3fd59d4eThen the state of the table is getting reset somewhere in your code.
@awcodes Indeed, like I mentioned in my original comment the data is reset when livewire update.
Here is a dump of
$practicesData
at page load, and once livewire update.
But I don't know why, the code doesn't interact with LiveWire at all, and it was working before I added ->live()
on a entirely different field of the form.We're probably not passing the data from the Controller to the Field correctly, and that's why when LiveWire re-render, the data is now null. But I don't know what's the right way and I can't seem to find docs about this. I'm trying to understand the source code of other filament field, but I'm not knowledgeable enough with livewire and filament to understand yet
Honestly, I’m not totally sure what is happening. Do you have a repo I can look at?
Somewhere the state is getting lost
Sadly no, it's on a private Gitlab instance.
Maybe I can ask someone tomorrow and see.
But I doubt the error comes from somewhere else than the 2 code snipped.
Odd, if I dump
$getStateValues();
. I have a value on first render and on livewire update.
So the data problem is only with $getPracticesData();
Ok, fair enough, but getPracticesData() is unique to your app, so it hard to give advice on that.
You can see the code in the first code snippet, my bad for not including it in the second code snipped (when I did the cleanup in price-matrix.blade.php).
I've updated it, you can see the code here: https://gist.github.com/mrleblanc101/a88deb517a594ed9adfadc1c3fd59d4e#file-practicematrix-php
Where is $practiceaData coming from? $component->practicesData($practiceData);
It’s not being injected into the call back nor is it being accessed from the component.
Wdym 🤔
The line just above it
$practiceData = self::getPracticeData($record->id);
I’m referring to the setUp method.
Yes, this ?
You’re right. Sorry.
Wish I had a better answer but it feels like a dom diffing issue to me that I think a wire:key would solve.
But you said it didn’t help.
I've added wire:key to all element in the @foreach, i didn't know it was needed.
I'm a Vue.js guy, so it make sense that it would work the same way
Hopefully someone else has a better answer.
But maybe it has something to do with the nested foreach loop.
Maybe that’s creating a weird dom diffing issue
I've deleted all HTML from my component, only kept the
dump
and the array is empty when LiveWire update:
I have no idea how to debug this, seems like if it was a DOM difing issue, it would be logged to the console, no ?Not necessarily
Yea. Not sure. Sorry. Somewhere the state is getting lost in the request.
I'm not even sure I understand what is called when LiveWire update, the whole
setUp
, just afterStateHydrated
, something else ?
I litteraly remove everything from setUp
and only left static hardcoded data, and the value are also lost 😭
Could this be a bug in Filament or LiveWire and not in our code 😮Just noticed filament is a couple version outdated
3.2.73
instead of the current 3.2.97
.
Will try that
Nope, not it 😦
@awcodes I think I found a solution, I do know if it's correct or clean tho.
So instead of calling $getPracticesData()
(with an "s") in the template.
I call $getPracticeData()
without an "s" in the template, the issue I had is that it require an id
params (public static function getPracticeData($id)
) which was received from afterStateHydrated
in the setUp
.
But from the doc I saw I could get the record in the template using $getRecord()
which mean I can use $practicesData = $getPracticeData($getRecord()->id);
If it works it isn’t wrong. It may or may not possibly be more clean or optimized, but if it works it’s not wrong.
Solution
I guess so, first time using filament and livewire, and this code wasn't from me.
But it kinda feels wonky to call PHP methods from the template 😬
Seems like it should be in the Controller and passed down, but that's where it reset the array when LireWire update.
But i'm very unfamillar with how to pass data from the Controller to the field, there is basically zero documentation about that. Only how to do a very basic
ViewField::make()
Sometimes you have to break convention to accomplish the goal.
Doesn’t make it right or wrong.
Well nvm, nothing save anymore lol
But hey, at least the field doesn't disappear 🤷♂️
Ok, but that might be related to my earlier refactor to change
<input>
and <select>
to <x-filament::input>
and <x-filament::input.select>
Ah no, it's ok. Just a bug from when I reverted the composer.lock
and public/
assets so that I didn't push unecessary changes.
I re-ram composer install
and php artisan filament:upgrade
to properly revert to the previous version.
I'll upgrade everything in another branch / merge-request later
Thanks a lot for your help @awcodes 🚀