With laravel 7 /livewire 1.3 app in login form I got errors on invalid form with code:
public function submit()
{
$loginRules= User::getUserValidationRulesArray();
$this->validate($loginRules);
and shows error message near with any field
I want on login fail to add flash message and reading at https://laravel.com/docs/7.x/validation
I try to make :
$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);
if ($validator->fails()) {
session()->flash('danger_message', 'Check your credentials !');
return redirect()->to('/login');
}
I got flash message, but validation errors for any field is lost.
If I try to make :
$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);
if ($validator->fails()) {
session()->flash('danger_message', 'Check your credentials !');
return redirect('/login')
->withErrors($validator)
->withInput();
}
and I got error :
Method Livewire\Redirector::withErrors does not exist.
in routes/web.php I have :
Route::livewire('/login', 'login')->name('login');
MODIFIED : In component app/Http/Livewire/Login.php :
<?php
namespace App\Http\Livewire;
use App\User;
use Illuminate\Support\Facades\Validator;
use Livewire\Component;
use Auth;
use DB;
use App\Config;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
class Login extends Component
{
public $form= [
'email'=>'admin@mail.com',
'password'=> '111111',
];
private $view_name= 'livewire.auth.login';
public function submit()
{
$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);
if ($validator->fails()) {
session()->flash('danger_message', 'Check your credentials !');
return;
// return redirect()->to('/login');
}
$user = Sentinel::findByCredentials(['email' => $this->form['email']]);
if (empty($user)) {
session()->flash('danger_message', 'User "' . $this->form['email'] . '" not found !');
...
and template resources/views/livewire/auth/login.blade.php :
<article >
@include('livewire.common.alert_messages')
<form class="form-login" wire:submit.prevent="submit">
<div class="card">
@if ($errors->any())
Check your login credentials
@endif
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<div class="card-body card-block">
<h3 class="card-header">
<span class="spinner-border" role="status" wire:loading>
<span class="sr-only">Loading...</span>
</span>
Login
</h3>
<h4 class="card-subtitle">Use your credentials</h4>
<dl> <!-- email FIELD DEFINITION -->
<dt>
<label class="col-form-label" for="email">Email:<span class="required"> * </span></label>
</dt>
<dd>
<input
wire:model.lazy="form.email"
name="email"
id="email"
class="form-control"
placeholder="Your email address"
autocomplete=off
>
@error('form.email')
<div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
</dd>
</dl> <!-- <dt> email FIELD DEFINITION -->
<dl> <!-- password FIELD DEFINITION -->
<dt>
<label class="col-form-label" for="password">Password:<span class="required"> * </span></label>
</dt>
<dd>
<input type="password"
wire:model.lazy="form.password"
id="password"
name="password"
class="form-control"
placeholder="Your password"
autocomplete=off
>
@error('form.password')
<div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
</dd>
</dl> <!-- <dl> password FIELD DEFINITION -->
</div> <!-- <div class="card-body card-block"> -->
<section class="card-footer row_content_right_aligned">
<button type="reset" class="btn btn-secondary btn-sm m-2">
Reset
</button>
<button type="submit" class="btn btn-primary btn-sm m-2 ml-4 mr-4 action_link">
Submit
</button>
</section>
</div> <!-- <div class="card"> -->
</form>
</article>
Which way is valid ?
Thanks in advance!
The beauty of Livewire is that you don't necessarily need to redirect to flash a message, you can display messages by setting properties on your component, and conditionally rendering them in your view. In this particular case, there's already logic readily available, you just have to check the errors-object being exposed by the validation.
In your view, all you have to do is check @if ($errors->any())
- if that's true, display your message. This is a Laravel feature, which Livewire implements. When any validation fails, an exception is thrown and intercepted, and the $errors
variable gets exposed to your view. This means that whenver you do $this->validate()
, and the validation fails, you can access the errors within $errors
.
<div>
@if ($errors->any())
Check your login credentials
@endif
<form wire:submit.prevent="submit">
<input type="text" wire:model="email">
@error('email') <span class="error">{{ $message }}</span> @enderror
<input type="password" wire:model="password">
@error('password') <span class="error">{{ $message }}</span> @enderror
<button type="submit">Submit</button>
</form>
</div>
Use the $rules
attribute to declare the rules, validate those rules with $this->validate()
and Livewire will do most of the work for you. You do not need to return any redirects, or use session()->flash()
. The session-state will not be flashed, because you don't perform a new page load.
class Login extends Component
{
public $form = [
'email' => 'admin@mail.com',
'password' => '111111',
];
protected $rules;
private $view_name = 'livewire.auth.login';
public function submit()
{
$this->rules = User::getUserValidationRulesArray('login');
$this->validate();
// No need to do any more checks, $errors will now be updated in your view as the exception is thrown
// Proceed with submitting the form