Error Bag disappears from a Laravel Livewire Blade template
Asked Answered
C

1

6

The following piece of PHP code works to capture input from a Livewire form. The form updates a user's password, and for the keen-eyed amongst you, you may find that large sections of it are taken from the Laravel Fortify framework.

/**
 * Validate and update the user's password.
 *
 * @param  mixed  $user
 * @param  array  $input
 * @return void
 */
public function update($user, array $input)
{
    try {
        Validator::make($input, [
            'current_password' => ['required', 'string'],
            'password' => $this->passwordRules(),
        ])->after(function ($validator) use ($user, $input) {
            if (! isset($input['current_password']) || ! Hash::check($input['current_password'], $user->password)) {
                $validator->errors()->add('current_password', __('The provided password does not match your current password.'));
            }
        })->validateWithBag('updatePassword');
    } catch (\Illuminate\Validation\ValidationException $e) {
        dd ($e);
    }

    $user->forceFill([
        'password' => Hash::make($input['password']),
    ])->save();
}

If a user enters invalid data, the dd($e); line of code shows me the exception object. The exception object thrown at this point contains an error bag named updatePassword. This is to be expected because the validateWithBag() function dictates that this should be so.

All good so far. However...

If I try to capture the error in the Livewire template (or for that matter, any Blade template), the named error bag disappears. To prove the point, the following <div> does appear when a current_password error is detected.

@error ('current_password')
    <div>Show error here: {{ $message }}</div>
@enderror

But the following <div> does not get shown by the framework:

@error ('current_password', 'updatePassword')
    <div>Show error here: {{ $message }}</div>
@enderror

If I try to echo out the $errors object from the blade template itself, then the object type is no longer of type \Illuminate\Validation\ValidationException, but rather of type Illuminate\Support\ViewErrorBag.

@php dd($errors); @endphp

Perhaps this is to be expected. But the problem is that the only error bag contained in this $errors object is 'default'. The error messages themselves are correct, but they are not in the bag I would expect them to be in.

Why is this?!

It's not a huge problem per-se, but it would be nice to understand what's going on. As the application expands, it becomes increasingly likely that a clash in error-message-id could lead to unexpected behaviour.

Conceptionconceptual answered 17/8, 2021 at 20:2 Comment(1)
still the same problem..Stanleigh
B
2

What is going on, is that the author of Livewire did not include the logic to support multiple errorbags yet. So currently all the errors, from all bags are gathered into a single one.

The author is almost ready to release version 3 of Livewire. Let's hope this specific feature is included then... :)

Until that is solved, you could fiddle around with setting some session variables that could work as some kind of errorbag-indicator:

catch (\Illuminate\Validation\ValidationException $e) {
  session()->flash('updatePassword', true);
}
Bortman answered 4/11, 2022 at 20:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.