formatStateUsing on simple repeater component

Is there a reasonable way to apply formatStateUsing to the component in a simple repeater, without reimplementing the logic in the repeater to format the array with UUID keys? Applying it directly to the component fails, as formatStateUsing/afterStateHydrated are called on the child component before the repeater component is hydrated, so $state is always null. Applying it to the repeater itself requires reimplementing the logic in Repeater::afterStateHydrated to assign UUIDs to each array, which seems fragile.
15 Replies
awcodes
awcodes8mo ago
I image any of the state updated methods by actions are getting called on the field component and not the child component based on what I’ve seen recently with the builder. But you should be able to override the actions to include calling ->afterStatedUpdated directly in the child too. Builder is certainly different from repeater, but I think they are fundamentally the same process.
Tetracyclic
TetracyclicOP8mo ago
This isn't from an action on the repeater, just formatting the stored data on output. dehydrateStateUsing on the child components works correctly, it's just the initial formatting on first load.
awcodes
awcodes8mo ago
Does hydrateStateUsing() not work? Or afterStateHydrated(), it think that’s the right modifier. So, afterStatedHydrated() allows you to change the $component->state()
Tetracyclic
TetracyclicOP8mo ago
Not on the child component, it has no state initially, the state is set afterwards by the parent component's afterStateHydrated
awcodes
awcodes8mo ago
Right, but it the case of a repeater it’s just a matter of changing the state on the field to whatever array you need it to be. The state of repeaters is fed down to the children. The children don’t maintain their own state.
Tetracyclic
TetracyclicOP8mo ago
Sure, but my understanding is that you need to format it with the UUIDs, as you're overriding the default afterStateHydrated, which formats the state from the model to have the UUID keys Which is fine, just not very elegant and won't track changes if Repeater gets updated.
awcodes
awcodes8mo ago
$component->generateUuid()
awcodes
awcodes8mo ago
It should handle them gracefully.
Tetracyclic
TetracyclicOP8mo ago
Just wanted to check that there wasn't a cleaner way of doing it, in case the logic there gets updated in future.
awcodes
awcodes8mo ago
Fair enough. UUIDs can be tricky when wanting to working with the state. Unfortunately. They are kinda required to work with the sorting aspect and passing the item back for the actions as arguments.
Tetracyclic
TetracyclicOP8mo ago
Yeah, ideally I'd mutate the state before it gets passed in to the repeater's afterStateHydrated, so it's only operating on the plain array that's stored in the database, then Repeater can take care of the logic for handling its state.
awcodes
awcodes8mo ago
Maybe. But afterStateHydrated allows for resetting the components state, because at that point it has the raw data. It doesn’t have the raw data before that. At least to my understanding.
Tetracyclic
TetracyclicOP8mo ago
Yeah, I'm thinking perhaps refactor this logic out to an attribute on the model, rather than have it at the Filament level.
awcodes
awcodes8mo ago
I use it to force Curator data into an array as a normalization of the state so I don’t have to check if it’s an array or not through out the plugin. Use it in Tiptap and scribble too to force the state into json for the editor .
Want results from more Discord servers?
Add your server