Laravel 5.2 - not show errors - validation

It's impossible to show errors in views
here is my Controller:
public function create(){
return view('articles.create');
}
public function store(Request $request){
$this->validate($request, [
'title' => 'required|max:5',
'content' => 'required',
]);
}
this is my view create.blade.php:
#if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<strong>Whoops!</strong> Something went wrong!.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Kernel.php
ShareErrorsFromSession already there
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
here is the route.php
i have added the route in web
Route::group(['middleware' => ['web']], function () {
Route::get('articles/create', 'ArticlesController#create'); // Display a form to create an article...
});
Route::get('articles', 'ArticlesController#index'); // Display all articles...
Route::post('articles', 'ArticlesController#store'); // Store a new article...
Route::get('articles/{id}', 'ArticlesController#show');

You can try something like this.
$data = array();
$messages=array(
'required' => "You can't leave this empty",
);
$datavalidate = array(
'name' => $request->name,
);
$rules = array(
'name' => 'required',
);
$validator = Validator::make($datavalidate,$rules,$messages);
if($validator->fails()){
return Redirect::back()->withErrors($validator);
}
And now print it on the view file.
{!! dd($errors) !!}

Related

Validation of Laravel does not show me the errors in the view

I have this in the controller...
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'category_id' => 'required',
'description' => 'required',
'price' => 'required',
'long_description' => 'required'
]);
$product = new Product();
foreach ($request->all() as $key => $value) {
if ($key !== '_token') $product->$key = $value;
}
$product->save();
return redirect('/admin/products');
}
And this in the view...
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{‌{ $error }}</li>
#endforeach
</ul>
</div>
#endif
The form without the validation works perfect. But I do not understand why he does not show me the errors in the view when redirected.
You need to do something like this-
public function store(Request $request)
{
$request->validate($request, [
'name' => 'required',
'category_id' => 'required',
'description' => 'required',
'price' => 'required',
'long_description' => 'required'
]);
if (!$validator->fails()) {
$product = new Product();
foreach ($request->all() as $key => $value) {
if ($key !== '_token') $product->$key = $value;
}
$product->save();
return redirect('/admin/products');
} else {
\Session::flash('errors', $validator->messages());
return redirect()->back()->withInput();
}
}
I made two changes in your code-
Added validate method on $request instead of $this.
Added a check for failed validation and sent those errors through a session.
I have already solved. The problem was that I had the post route inside api.php. By moving it to web.php it works.

Error App\Http\Requests\AddUserRequest::fails does not exist

I get this error when I want to insert data into the table and return a message.
Here is my code.
When I entered the form and submitted, an error occurred: Method App\Http\Requests\AddUserRequest::fails does not exist.
Code In Router:
/**************Quản lý user*****************/
Route::get('admin/manage-user', 'UserController#getList')->middleware('admin');
Route::get('admin/manage-user/add', 'UserController#indexAdd')->middleware('admin');
Route::post('admin/manage-user/add', 'UserController#getAdd')->middleware('admin');
Code In UserController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Http\Requests\AddUserRequest;
class UserController extends Controller
{
//
public function getList()
{
$data = User::paginate(10);
return view('admin.manage-user',['data' => $data]);
}
public function indexAdd()
{
return view('admin.add-user');
}
public function getAdd(AddUserRequest $request)
{
if($request->fails())
{
return redirect('admin.add-user')
-> withInput()
-> withErrors($request);
}else
{
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
}
}
Code In view:
#extends('layouts.admin')
#section('title','Add User')
#section('content')
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Add User</h3>
</div>
<!-- /.box-header -->
<!-- form start -->
<form role="form" action="{{url('admin/manage-user/add')}}" method="post">
<div class="box-body">
#csrf
<div class="form-group">
#if (session('success'))
<div class="alert alert-success">
<p>{{ session('success') }}</p>
</div>
#endif
#if ($errors->any())
<div class="alert alert-danger">
<b>Lỗi!! Bạn vui vòng kiểm tra lại:</b>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
</div>
In AddUserRequest:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
class AddUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'username' => 'required|max:200',
'email' => 'required|email|unique:users',
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
];
}
}
Thank you for your help!
you don't need to put that check, because data is already validated through your request
public function getAdd(AddUserRequest $request)
{
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
AddUserRequest is a FormRequest it doesn't have fails method. For FormRequest you don't need to check fails, it automatically validate your request data using rules provided in that class and throw validation error, for details check here.
For FormRequest validation you use it like this
public function getAdd(AddUserRequest $request)
{
//all code here executed after validation
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
If you need to check validation in you controller then use manual validation like this.
public function getAdd(Request $request)
{
$validator = Validator::make($request->all(), [
'username' => 'required|max:200',
'email' => 'required|email|unique:users',
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
]);
if($validator->fails())
{
return redirect('admin.add-user')
-> withInput()
-> withErrors($request);
}else
{
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
}

Laravel 5.2: withErrors on redirect not working

I'm currently struggling with a Laravel problem I can't fix myself. If I pass errors using withErrors() the errors are not passed to the Error Bag ($errors).
My Controller (FormController):
public function contact(Request $request) {
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'message' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput($request->all());
}
return redirect()->back();
}
The thing is, also withInput() is not working. Where could the problem come from? I appreciate your help!
(Part of) the defined routes.php:
Route::group(['middleware' => 'web'], function(){
Route::post('/contact', 'FormController#contact');
});
Session config
return [
'driver' => env('SESSION_DRIVER', 'memcached'),
'lifetime' => 120,
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => null,
'table' => 'sessions',
'lottery' => [2, 100],
'cookie' => 'session',
'path' => '/',
'domain' => null,
'secure' => false,
];
In Laravel 5.2 you need to use the web middleware in your routes to pass the errors to the view.
Route::group(['middleware' => ['web']], function () {
Route::get('/', function() {
return view('welcome');
});
});
Don't pass anything to the withInput
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
and use the old function to get the flashed data
$name = $request->old('name');
or
{{old('name')}}
Hope it helps
If the controller that you are redirecting to is also using withErrors() function, the error messages in redirect()->back()->withErrors($validator) will be overwritten.
But, the old messages are still in session. So you can still read and display them with session('errors'):
#if ($errors->any())
<div class="alert alert-danger">
<ul class="my-0">
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#elseif (null !== session('errors') && session('errors')->any())
<div class="alert alert-danger">
<ul class="my-0">
#foreach (session('errors')->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
This can be due to session problem. To diagnose this problem use print_r($request->session()). if you are getting different id in session object that means session is not setting up properly.
To get it done open Kernel.php
dont specify below line in $middleware array
specify these below line in web middleware group and $middlewarePriority array
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,

Laravel 5.2 validation errors

I have some trouble with validation in Laravel 5.2
When i try validate request in controller like this
$this->validate($request, [
'title' => 'required',
'content.*.rate' => 'required',
]);
Validator catch error, but don't store them to session, so when i'm try to call in template this code
#if (isset($errors) && count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Laravel throw the error
Undefined variable: errors (View: /home/vagrant/Code/os.dev/resources/views/semantic/index.blade.php)
When i'm try validate with this code
$validator = Validator::make($request->all(), [
'title' => 'required',
'content.*.rate' => 'required'
]);
if ($validator->fails()) {
return redirect()
->back()
->withInput($request->all())
->withErrors($validator, 'error');
}
Variable $error also not available in template but if i try to display errors in controller
if ($validator->fails()) {
dd($validator->errors()->all());
}
Errors displays but i can't access to them from template.
What's wrong?
Update as of Laravel 5.2.27
Laravel now supports the web middleware by default as you can see here: source
In other words, you no longer need to wrap your routes around the web middleware group because it does it for you in the RouteServiceProvider file. However, if you are using a version of Laravel between 5.2.0 and 5.2.26, then refer to the method below:
Below only applies to Laravel 5.2.0 to 5.2.26
Without seeing your routes.php or Kernel.php file, here is what I suspect is happening.
The way middlewares work has changed from 5.2 and 5.1. In 5.1, you will see this in your app/Http/Kernel.php file:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
];
This array is your application's global HTTP middleware stack. In other words, they run on every request. Take a note at this particular middleware: Illuminate\View\Middleware\ShareErrorsFromSession. This is what adds the $errors variable on every request.
However, in 5.2, things have changed to allow for both a web UI and an API within the same application. Now, you will see this in that same file:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
The global middleware stack now only checks for maintenance. You now have a middleware group called "web" that includes a bulk of the previous global middleware. Remember that it is like this to allow for both a web UI and an API within the same application.
So how do we get that $errors variable back?
In your routes file, you need to add your routes within the "web" middleware group for you to have access to that $errors variable on every request. Like this:
Route::group(['middleware' => ['web']], function () {
// Add your routes here
});
If you aren't going to build an API, another option is to move the "web" middlewares to the global middleware stack like in 5.1.
Try using
return redirect()->back()
->withInput($request->all())
->withErrors($validator->errors()); // will return only the errors
Try to replace:
->withErrors($validator, 'error');
with:
->withErrors($validator);
// Replace
Route::group(['middleware' => ['web']], function () {
// Add your routes here
});
// with
Route::group(['middlewareGroups' => ['web']], function () {
// Add your routes here
});
I have my working validation code in laravel 5.2 like this
first of all create a function in model like this
In model add this line of code at starting
use Illuminate\Support\Facades\Validator;
public static function validate($input) {
$rules = array(
'title' => 'required',
'content.*.rate' => 'required',
);
return Validator::make($input, $rules);
}
and in controller call this function to validate the input
use Illuminate\Support\Facades\Redirect;
$validate = ModelName::validate($inputs);
if ($validate->passes()) {
///some code
}else{
return Redirect::to('Route/URL')
->withErrors($validate)
->withInput();
}
Now here comes the template part
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
and Above all the things you must write your Route like this
Route::group(['middleware' => ['web']], function () {
Route::resource('RouteURL', 'ControllerName');
});
Wrap you Routes in web middleware like below:
Route::group(['middleware' => ['web']], function () {
// Add your routes here
});
and In app\Http\Kernel.php move \Illuminate\Session\Middleware\StartSession::class from the web $middlewareGroups to $middleware
Hope it will solve your problem.
Route
Route::group(['middlewareGroups' => ['web']], function () {
// Add your routes here
Route::resource('/post', 'PostController');
});
Functions
public function store(Request $request){
$this->validate($request, [
//input field names
'title' => 'required|max:20',
'body' => 'required',
]);
}
View
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
This will work
Route::group(['middlewareGroups' => ['web']], function () {
// Add your routes here
});
as well as this also works
Route::post('location',array(
'as'=>'location',
'middlewareGroups'=>'web',
'uses'=>'myController#function'
));
// Controller
$this->validateWith([
'title' => 'required',
'content.*.rate' => 'required',
]);
// Blade Template
#if ($errors->has('title'))
<span class="error">
<strong>{{ $errors->first('title') }}</strong>
</span>
#endif
#if ($errors->has('anotherfied'))
<span class="error">
<strong>{{ $errors->first('anotherfied') }}</strong>
</span>
#endif
Find the documentation.

Laravel flash message validation

I am creating a CRUD of books and what I wanted to do is like the generated auth files that if someone registers and didn't input any in the textbox, a flash message will return. I am doing that now in my crud but I can only make a flash message when a book is successfully created. This is my store function
public function store(Request $request)
{
$this->validate($request, [
'isbn' => 'required|',
'title' => 'required',
'author' => 'required',
'publisher' => 'required'
]);
Session::flash('msg', 'Book added!');
$books = $request->all();
Book::create($books);
return redirect('books');
}
And in my home.blade.php
#if(Session::has('msg'))
<div class="alert alert-success">
{{ Session::get('msg') }}
</div>
#endif
This actually works but I want to show some ready generated error flash when someone didnt complete fields. How can I do that?
It's pretty simple, first there's a sweet nice feature that is the redirect()->with()
So your controller code could be:
public function store(Request $request)
{
$this->validate($request, [
'isbn' => 'required|',
'title' => 'required',
'author' => 'required',
'publisher' => 'required'
]);
if(Book::create($books)){
$message = [
'flashType' => 'success',
'flashMessage' => 'Book added!'
];
}else{
$message = [
'flashType' => 'danger',
'flashMessage' => 'Oh snap! something went wrong'
];
}
return redirect()->action('BooksController#index')->with($message);
}
Then on your view:
#if (Session::has('flashMessage'))
<div class="alert {{ Session::has('flashType') ? 'alert-'.session('flashType') : '' }}">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{{ session('flashMessage') }}
</div>
#endif
Bonus you can put this on your footer, so the alerts boxes will vanish after 3 seconds:
<script>
$('div.alert').delay(3000).slideUp(300);
</script>
You could get the individual errors for a field
{!! $errors->first('isbn'); !!}
or you can get all the errors
#foreach ($errors->all() as $error)
<div>{{ $error }}</div>
#endforeach
you can use try catch like this
try{
$books = $request->all();
Book::create($books);
Session::flash('msg', 'Book added!');
}
catch(Exception $e){
Session::flash('msg', $e->getmessage());
}

Resources