Why error messages doesn't Appear in Laravel views? - laravel

I want to pass custom validation messages to my view using a custom request when storing a role.
I have create a new Request called StoreRoleRequest
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Contracts\Validation\Validator;
class StoreRoleRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required'
];
}
protected function formatErrors(Validator $validator)
{
return $validator->errors()->all();
}
public function messages()
{
return [
'name.required' => 'the name of the Role is mandatory',
];
}
}
And then pass this custom Request to my store function in the RoleController like this:
public function store(StoreRoleRequest $request)
{
Role::create($request->all());
return redirect(route('role.index'));
}
I have a view that show the create role form where the validation seems to work properly but without showing me error even if i call them into the view like this:
{!! Former::open()->action(route('role.store')) !!}
#if (count($errors->all()))
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</div>
#endif
{!! Former::text('name')->label('Groupe name') !!}
{!! Former::text('display_name')->label('Displayed name') !!}
{!! Former::text('description')->label('Description') !!}
{!! Former::actions( Button::primary('Save')->submit(),
Button::warning('Clear')->reset() ,
Button::danger('Close')->asLinkTo('#')->withAttributes(['data-dismiss' => 'modal'])
)!!}
{!! Former::close() !!}
Has anyone an idea why the errors doesn't appear into the view ? am I looping something inside the custom Request ?
EDIT
NB: Even in the login and the registration form the errors doesn't appear anymore.
In this case i have change my middlware that was pointed to web ['middleware' => ['web'] to this:
Route::group(['middleware' => []], function ()
{
// other routes
Route::resource('role', 'RoleController');
});
and all my errors displayed perfectly.
have you locate the root cause about this issue ?

After your question update it seems, you have newer version of Laravel application (don't confuse it with Laravel framework).
To verify this, open file app/Providers/RouteServiceProvider.php and verify method what's the content of map method. In case it launches mapWebRoutes it means that you have 5.2.27+ application which applies web group middleware automatically.
In case web middleware is applied automatically you shouldn't apply web middleware in your routes.php file because it will cause unexpected behaviour.
So you should either remove web middleware from your routes.php in case you have mapWebRoutes defined in your RouteServiceProvider class or you can modify your RouteServiceProvider class to not apply web group middleware automatically. It's up to you which solution you choose.
Just for quick reference:
RouteServiceProvider for Laravel application 5.2.24
RouteServiceProvider for Laravel application 5.2.27

Try to ask if errors exists by this way:
#if($errors->any())
// Your code
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
// More code
#endif
Also remove the formatErrors function from the request... You don't need it...
The function messages() is responsible for returning your custom messages...
Regards.

Related

How do you send validation errors to a blade view using the Validator facade? Error: Serialization of 'Closure' is not allowed

How do I use validateWithBag90 in Laravel 9? I tried a lot of combinations and I'm getting a bit frustrated.
$validator = Validator::make($request->all(), [
'old' => 'required',
'new' => 'required|string|confirmed',
]);
if ($validator->fails()) {
return redirect()->back()->with('error', $validator);
}
I'm getting this error.
Serialization of 'Closure' is not allowed
Any ideas?
Manually Creating Validators
After determining whether the request validation failed, you may use
the withErrors method to flash the error messages to the session. When
using this method, the $errors variable will automatically be shared
with your views after redirection, allowing you to easily display them
back to the user. The withErrors method accepts a validator, a
MessageBag, or a PHP array.
Instead of:
// ...
->with('error', $validator); ❌
// ...
Use this:
// ...
if ($validator->fails()) {
return redirect()
->back()
->withErrors($validator) ✅
->withInput();
}
// ...
Addendum
Displaying The Validation Errors
An $errors variable is shared with all of your application's views
by the Illuminate\View\Middleware\ShareErrorsFromSession middleware,
which is provided by the web middleware group. When this middleware is
applied an $errors variable will always be available in your views,
allowing you to conveniently assume the $errors variable is always
defined and can be safely used. The $errors variable will be an
instance of Illuminate\Support\MessageBag.
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<!-- Create Post Form -->

Laravel send email to address from database

In my index view I show all the users and there is a button that will change the user status to active and not active. The code looks like this:
#foreach($users as $user)
<tr>
<td>{{$user->name}}</td>
<td>{{$user->surname}}</td>
<td>{{$user->email}}</td>
<td>
#if($user->is_active == 0)
{!! Form::model($user, ['method' => 'PUT', 'action'=>['AdminUserController#activateuser', $user->id]]) !!}
{!! Form::submit('Activate', ['class'=>'btn btn-primary']) !!}
{!! Form::close() !!}
#else
{!! Form::model($user, ['method' => 'PUT', 'action'=>['AdminUserController#activateuser', $user->id]]) !!}
{!! Form::submit('De-Activate', ['class'=>'btn btn-danger']) !!}
{!! Form::close() !!}
#endif
</td>
<td>{{$user->cell}}</td>
<td><button class="btn btn-primary">View Property</button></td>
<td><button class="btn btn-danger">Delete</button></td>
</tr>
#endforeach
So when I click on activate/deactivate button I trigger my activateuser function of the controller. After activation, an email is sent.
The controller looks like this:
public function activateuser(Request $request, $id){
$user = User::findOrFail($id);
if($user->is_active == 0){
$user->update([$user->is_active = 1]);
Mail::send(new activateUser());
}
else{
$user->update([$user->is_active = 0]);
}
return redirect()->back();
}
At the moment the email is going to myself and my Mailabçe looks like this:
public function build()
{
return $this->view('emails.activateuser')->to('wosleybago#gmail.com');
}
What I want instead is to send the email to the email address from the user email in the database table.
How can I do that?
So, someho I should get the $user->email
I usually want my emails have all the information in itself, so I pass User instance or whatever instance that holds data required to compose the mail.
So the Mailable has __construct(..) like this:
/**
* #var \App\User
*/
public $user; // since this is a public property its going to be available in view of mailable as $user
__construct(App\User $user) {
$this->user = $user;
// further more I set the to(), this is what you are after
$this->to($user->email, $user->name);
// and subject
$this->subject('You are activated!');
}
...
And now all you need to do in the controller is the following:
Mail::send(new activateUser($user));
As mentioned above, $user is available in the mail-view so you can use it there as well:
Hi, {{ $user->name }},
...
Note: change the activateUser to ActivateUser to follow PSR-2
Class names MUST be declared in StudlyCaps.
I also use queued mails so I set the $timeout and $tries properties right on the Mailable class.
Sending email is described in Doc: https://laravel.com/docs/5.6/mail#sending-mail
Put this code inside activateUser() function
Mail::to($user)->send(new YourMailableName());
Do not forget to import Mail and YourMailableName using "use" keyword.
Or you can use user email instead object
Mail::to($user->email)->send(new YourMailableName());
And remove ->to('wosleybago#gmail.com') from your Mailable/
You should pass User Email in when creating new activateUser instance, like so
Mail::send(new activateUser($user->email));
And then use this attribute later.
Sending Email to particular a person is quite simple. My suggestion would be as follows:
Use Queue to send mail later as it will take some time to respond from controller to view.
In existing code you can get the email of the current user and send it using a helper to() that comes with mail functionality of laravel.
You can code it like this.
if($user->is_active == 0){
$user->update([$user->is_active = 1]);
Mail::to($user->email)->send(new MailableClassInstance);
}

Laravel not reaching update method and returns edit view again – route wrong

When I click Save on my edit view, my routing brings back my edit view instead of my index view and my update method is never reached.
I noticed that I reach the update method if I remove “UsersRequest $request” from the method parameters. Not sure why, and if it’s related, but I need $request to do my update (see controller code below):
Routes:
Route::get('/users', 'UsersController#index')->name('users.index');
Route::patch('/users/{id}',
[
'as' => 'users.update',
'uses' => 'UsersController#update'
]);
Route::get('/users/{id}/edit', 'UsersController#edit');
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UsersRequest;
//public function update($id, UsersRequest $request)
public function update($id) //- with $request removed, the index view is displayed
{
$user = \Auth::user();
$user->update($request->all());
return view('users.index');
}
Edit view:
{!! Form::model($user, ['method' => 'PATCH', 'action' => [ 'UsersController#update', 'user' => $user->id ] ]) !!}
{!! Form::submit('Save', ['class'=>'btn primary']) !!}
{!! Form::close() !!}
Network after save button clicked
URL Protocol Method Result
/myapp/public/users/1 HTTP POST 302 Goes for the update route
http://000.000.000.000/myapp/public/users/1/edit HTTP POST 200 Redirects to the edit route??
.env
APP_URL=http://000.000.000.000/myapp/public
You're failing whatever validation is present in your UsersRequest form request. When the validation fails, it redirects you back to where you came from, which is your edit view. Your edit view should be updated to show the validation errors so that your users know what fields need to be fixed.
The reason it works when you remove the UsersRequest $request parameter is that the validation is no longer being performed.

Store method not working using resource route

I am having trouble figuring out why my data is not being posted and stored in my database. I have used the resource routes for another form and it works fine, but here for some reason it won't work. Clicking submit just seems to refresh the page, no errors to work from!
So I have a form which gets the workout routines from a database, and on submission I want this to create a new Workout "session" in my database table (called "Workouts"). The form is this:
{{ Form::open(array('url' => '/')) }}
<div class="form-group">
{{ Form::text('workout_name', Input::old('workout_name'), array('class' => 'form-control', 'placeholder' => 'Session Name')) }}
</div>
<div class="form-group">
{{ Form::select('routines', $routine_names, null, array('class' => 'form-control')) }}
</div>
{{ Form::submit('Select Routine', array('class' => 'btn btn-success pull-right')) }}
{{ Form::close() }}
In my HomeController I have this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Routine;
use App\Workout;
class HomeController extends Controller
{
public function index()
{
$routines = Routine::all();
$routine_names = Routine::lists('routine_name');
return view('workout')->with(array('routines'=>$routines, 'routine_names'=>$routine_names));
}
public function store()
{
$workout = new Workout;
$workout->workout_name = Input::get('workout_name');
$workout->save();
}
}
I have a model created for the Workout, and the route for this page is the following:
Route::resource('/', 'HomeController');
I can't figure out where I'm going wrong. The index method in my controller is working, as it is returning the correct view with the data I need. The form also looks OK I think, as I'm posting to the same page, but submitting doesn't seem to carry out the code I have in the store method of the HomeController.
Any help would be appreciated!
Thanks :)
Change your route declaration from:
Route::resource('/', 'HomeController');
To something like this:
Route::resource('/workout', 'WorkoutController');
If you are using the resources controller creator command of php artisan then all the specific routes are created for you. To see all listed routes you can type , php artisan routes. This will show you RESTFUL routes even for your POST method .
And also even you did not created the resources controller and did made the routes with manual way then you can create ,
Route::POST('/workout' , SomeController#post);
I am trying to say , you have to use the different POST method for the form submission .
Hope this will solve your problem . Thanks.

Laravel 5 and understanding MVC - How do I get the db data to my views?

I’m new to Laravel 5 and the world of MVC.
I’ve installed Laravel 5 boilerplate project and everything works fine, out of the box. I can register and then login to the app.
I kind of understand the roles of Routes, Controllers, Models and Views, but I can’t figure out the syntax to simply retrieve data from my users database table, and display it in my home view (using HomeController).
I’m not sure which piece of code goes where, and how the syntax should be coded. In the code below, I'm logged in as a user, and I'm simply trying to display all the users from the user table.
Can you help? If I can understand how to the get the data from my database to my views, I’ll be good to go. I'm looking for simple examples. I've seen I lot of examples on the web, but for most, I don't even know where (controller, route, etc.) to copy the code provided.
I get the following error with the code below:
FatalErrorException in HomeController.php line 52: Class 'App\Http\Controllers\User' not found
routes.php
Route::get('home', 'HomeController#index');
HomeController.php
<?php namespace App\Http\Controllers;
class HomeController extends Controller {
/*
|--------------------------------------------------------------------------
| Home Controller
|--------------------------------------------------------------------------
|
| This controller renders your application's "dashboard" for users that
| are authenticated. Of course, you are free to change or remove the
| controller as you wish. It is just here to get your app started!
|
*/
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard to the user.
*
* #return Response
*/
public function index()
{
$users = User::all();
return View::make('user.index', ['users' => $users]);
}
Home.blade.php
#extends('app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">List of users</div>
<div class="panel-body">
<table>
#foreach($users as $key => $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->name }}</td>
<td>{{ $value->email }}</td>
</tr>
#endforeach
</table>
</div>
</div>
</div>
</div>
</div>
#endsection
Laravel 5 is namespaced and PSR-4 autoloaded, so in your controller $users = User::all(); should be App\User::all(); or use App\User; on the top of the file after the namespace declaration.
Your view is also incorrect. This #foreach($users as $key => $value) should be #foreach($users as $user) then you access the users attributes as normal fields: $user->id, $user->name, etc.
Another thing, the laravel 5 way to make a view is this (yours is not incorrect, it's just different syntax):
return view('user.index')->with(['users' => $users]);
or with some sorcery:
return view('user.index')->withUsers($users);
Another tip that will really make you understand how stuff works: use tinker. Open up a console, go to the laravel folder and type php artisan tinker. There you can execute php code and check the output. Type User::all() and check the error. Then type App\User::all() and check the response.

Resources