livewire: Validation errors are not flashed to session
If a validation error happens in Livewire, the ViewErrorBag (or MessageBag?) is not flashed to session as Laravel validation normally does (check https://laravel.com/docs/master/validation#quick-displaying-the-validation-errors). This means that when validations occur inside Livewire components, we can’t access “session()->get(‘errors’)”.
This is a problem for new Laravel 7 components syntax. For example, when creating a custom input, I want to use the @error blade directive inside the component. For this to work, I need to set the error bag in a public $errors property, so it gets injected inside the component. Something like this:
class Input extends Component
{
public string $name;
public string $label;
public string $type;
public $errors;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(string $name, string $label, string $type = 'text')
{
$this->name = $name;
$this->label = $label;
$this->type = $type;
$this->errors = session()->get('errors') :? new ViewErrorBag(); //This does not work, since session()->get('errors') is null
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.input');
}
}
For now, we are doing this:
Input.php (component class):
class Input extends Component
{
public string $name;
public string $label;
public string $type;
public $errors;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(string $name, string $label, $errors, string $type = 'text')
{
$this->name = $name;
$this->label = $label;
$this->type = $type;
$this->errors = $errors;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.input');
}
}
input.blade.php (view):
...
<x-input name="email" type="email" label="E-mail" :errors="$errors"/> // Passing $errors on every component isn't a good solution
...
I tested and I can confirm that just changing the following code inside Livewire\Component@output method solves this issue. I submitted the PR #622 which does this:
public function output($errors = null)
{
...
...
$errors = (new ViewErrorBag)->put('default', $errorBag); //<- add this
$view->with([
'errors' => $errors, //<- change this
'_instance' => $this,
] + $this->getPublicPropertiesDefinedBySubClass());
session()->flash('errors', $errors); //<- add this
...
...
}
Thanks!!
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 22 (15 by maintainers)
@gjm this is Exactly what my PR, mentioned on this issue, fixes 😃 Just waiting for it to be merged too
Hello @mokhosh I guess it is another problem. I think you need to find a way of reseting the validations once you have closed your modal. Livewire has a reset method (not documented yet) and a $refresh method also that you can try calling using Javascript on modal close/open. Just some tips, you could try if you want.
I’ve just opened PR #704 that fixes the issue of
$errorsnot being available to nested components.