afterStateUpdated and field changed by $set()
The documentation says that afterStateUpdated does not work when a field changes via $set(). Sometimes, however, instead of the user, the field is just changed by $set(). How to deal with this?
For example, I have qty, price and total fields. The price field is ->live() and has afterStateUpdated() in which I set the total field after changing the price value. However, in some situations, the price field is set by $set(). How then to update the total field?
Solution:Jump to solution
You don’t inject it. Let’s say you have a quantity field and an item_price field and a total_price field.
Quantity and item_price are both set to reactive. That will force the form to re-render. So on the total_price field you can use afterStateUpdated() or afterStateHydrated() to $get(‘quantity’) and $get(‘item_price’), do the math and make the state of total_price equal to that value....
7 Replies
Don’t set the price field from other places. Use $get on the price field to total the other fields there.
How to inject data to price field by $get? By ->default() ?
Solution
You don’t inject it. Let’s say you have a quantity field and an item_price field and a total_price field.
Quantity and item_price are both set to reactive. That will force the form to re-render. So on the total_price field you can use afterStateUpdated() or afterStateHydrated() to $get(‘quantity’) and $get(‘item_price’), do the math and make the state of total_price equal to that value.
afterStateUpdated() on the total_price field? this field does not change state, there is only supposed to be the result of multiplication. Isn't afterStateUpdated() used on fields that are live()?
That’s why I also said afterStateHydrated.
If any of the form fields are reactive then the entire form get rehydrated
Thank you very much @awcodes ! This solves my problem. I learned something again 😉
Hello again @awcodes (sorry to bother you). I need to get back to this topic because I'm just starting to test this live today. Either I misunderstood your advice or it is not working as I assumed though. In the example below in the total field nothing happens if I change the qty and price fields. From what I understood, this function should execute after changing any field of the form that is live()?
public static function form(Form $form): Form
{
return $form
->schema([
Select::make('type')->label('Zestaw')->columnSpan(2)->live()
->options(
[1 => 'one', 2 => 'two', 3 => 'three']
)->afterStateUpdated(
function (Get $get) {
Debugbar::info('From afterStateUpdated: ' . $get('qty'));
}
),
TextInput::make('qty')->label('Ilość')->numeric()->live(onBlur: true),
TextInput::make('price')->label('Cena')->numeric()->live(onBlur: true),
TextInput::make('total')->label('Razem')->numeric()
->afterStateHydrated(
function (Get $get) {
Debugbar::info('From afterStateHydrated: ' . $get('qty'));
}
),
]);
}