Strange issue here! My return code within the controller is as follows:
return back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
And then I display the errors within blade:
#if ($errors->any())
<article class="message is-danger">
<div class="message-body">
<ul>
#foreach ($errors->all() as $error)
<li>{!! $error !!}</li>
#endforeach
</ul>
</div>
</article>
#endif
However this doesn't appear to be working at all, $errors is empty for some reason, however this works fine from another controller!
This is the method where this works, I have included the use classes.
namespace App\Http\Controllers;
use App\Pages;
use App\PlannerStatus;
use App\SubPages;
use App\VehicleMake;
use App\Website;
use App\WebsiteRedirects;
use Illuminate\Http\Request;
use Redirect;
class RedirectsController extends Controller
{
public function store(Request $request, Website $website)
{
$error = [ 'test' => 'test error' ];
if (!empty($error)) {
return back()->withErrors($error)->withInput();
}
return back();
}
}
And this is the controller where this does NOT work, as you can see they are the same, more or less!
namespace App\Http\Controllers;
use App\ResultsText;
use App\VehicleMake;
use App\VehicleModel;
use App\VehicleType;
use App\SearchPath;
use App\Website;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\MessageBag;
use Redirect;
class ResultsTextController extends Controller
{
public function update(Website $website, ResultsText $resultsText, Request $request)
{
$data = request()->except(['_token','id']);
$result = ResultsText::where('id', $resultsText->id)->update($data);
if (!$result) {
return back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
}
return Redirect::action('ResultsTextController#index', $website);
}
}
Also here are my Routes, just so you can see they are pretty much identical:
Route::prefix('/redirects')->group(function () {
Route::get('/', 'RedirectsController#index')->middleware('SettingStatus:redirect');
Route::patch('/update', 'RedirectsController#update');
});
Route::prefix('/results-text')->group(function () {
Route::post('{resultsText}/update', 'ResultsTextController#update');
});
Inside your blade try this
#if ($errors->any())
<article class="message is-danger">
<div class="message-body">
<ul>
#foreach ($errors as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
</article>
#endif
It's easily overlooked in your question. The problem is not what it seems. You will probably find it funny why it doesn't work.
Replace
return back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
with
return redirect()->back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
Related
I am new to laravel. I want to set laravel validation on form submit. I have write below code for validation validation works but on view it does not show me any error message
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use DB;
use Session;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\MessageBag;
use Illuminate\Pagination\LengthAwarePaginator;
and blow code in my register function
$input = Input::all();
$rules = array(
'first_name' => array('required'),
'last_name' => 'required');
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
$messages = $validator->messages();
// echo '<pre>';
// print_r($messages);
// exit;
// return redirect('admin/user/add')
// ->withErrors($validator)
// ->withInput();
return Redirect::back()->withErrors($messages);
}
to display I have use following code in my view
#if ($errors->any())
#foreach ($errors->all() as $error)
{{ $error }}
#endforeach
#endif
can anyone help me to solve this issue.
If there are validation errors, you should use $errors in your view to get them. The $errors variable is an instance of Illuminate\Support\MessageBag and Laravel always makes it available to your views. You can use it like this:
#if ($errors->any())
<div class="errors">
#foreach ($errors->all() as $message)
<p>{{ $message }}</p>
#endforeach
</div>
#endif
That will output all of your validation messages (if there are any) to your view. If you want to check to see if there's an error message for a specific field, you can use the has method. You can then use the first message to retrieve the first message for that field or the get method to retrieve them all. An example using first:
#if ($errors->has('your_field'))
<div class="error">{{ $errors->first('your_field') }}</div>
#endif
See here for more information
Validation messages are stored in $errors, which is globally passed to all views, and not in session()->get("message"), unless you specifically used that. With the above, you'd use
#if($errors->has("first_name"))
<p class="alert alert-info">{{ $errors->first("first_name") }}</p>
#endif
Do the same for all fields being validated and you should start seeing your error messages.
Do you override the function "showRegistrationForm"?
If Yes, you should override the function "register":
public function register(Request $request) {
$validation = $this->validator($request->all());
if ($validation->fails()) {
$errors = $validation->errors();
return view('auth.register', compact('errors'));
}
else {
$user = $this->create($request->all());
Auth::login($user);
return redirect('/')->with(['message'=>'Account Successfully Created.']);
}
}
I manually created a Validator, but i can't find a method to get the validated data.
For Request, validated data return from $request->validate([...])
For FormRequest, it's return from $formRequest->validated()
But with Validator, i don't see a method like those 2 above.
Assuming that you're using Validator facade:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), $rules, $messages, $attributes);
if ($validator->fails()) {
return $validator->errors();
}
//If validation passes, return valid fields
return $validator->valid();
https://laravel.com/api/5.5/Illuminate/Validation/Validator.html#method_valid
If you use the Validator facade with make it will return a validator instance. This validator instance has methods like validate(), fails() and so on. You can look those methods up in the validator class or in the laravel api-documentation.
Writing The Validation Logic
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
Displaying The Validation Errors
<!-- /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 -->
I am trying to validate a simple form by using Laravel's validator. Looks like validation works fine but i am unable to display errors. Form and controller looks like this.
Form
<h3>Add a New Team</h3>
<form method="POST" action="/teams">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<input class="form-control" name="team_name" value="{{ old('team_name') }}" />
</div>
<div class="form-group">
<button type="submit" class="btn bg-primary">Add Team</button>
</div>
</form>
#if(count($errors))
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Controller Method
public function store(Request $request) {
$this->validate($request, [
'team_name' => 'required|min:10'
]);
$team = new Team;
$team->team_name = $request->team_name;
$team->save();
return back();
}
If i remove web middleware group from my routes, errors displays fine.
Currently my routes.php file looks like this
Route::group(['middleware' => ['web']], function () {
Route::get('/teams', 'TeamsController#create');
Route::post('/teams', 'TeamsController#store');
});
How do i fix this problem ? Any help would be appreciated.
why do use the validation looks like laravel 4 while you are using laravel 5!!
in laravel 5 you need first to make Request class that handle your validation
php artisan make:request RequestName
you will find the request class that you make in
'app/http/Requests/RequestName.php'
and in the rules function you can handle your validation
public function rules()
{
return [
// put your validation rules here
'team_name' => 'required|min:10'
];
}
finally in your controller
use App\Http\Requests\RequestName;
public function store(RequestName $request) {
Team::create($request->all());
return Redirect::back();
}
for more illustration here
I recommend you to use Laravel Form Request
run
artisan make:request TeamRequest
add some logic and rules
class TeamRequest extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true; //you can put here any other variable or condition
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
// put your validation rules here
];
}
}
then your contorller code will be like so:
public function store(TeamRequest $request)
{
$team = Team::create($request->all());
return back();
}
you no longer need to validate request and redirect back with errors and other stuff, laravel will do it for you
And you code looks more clean and neat, isn't it?
Write below code in your controller :
// define rules
$rules = array(
'team_name' => 'required|min:10'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
// something
return Redirect::back()
->withErrors($validator) // send back all errors to the login form
->withInput();
}
else
{
// something
// save your data
$team = new Team;
$team->team_name = $request->team_name;
$team->save();
}
change in View File :
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
After a little bit research, i have found that Laravel 5.2 has a RouteServiceProvider and it includes web middleware group for all routes. So i do not have to add the web middleware group to my routes manually. I just removed it from routes.php and problem solved.
If i remove web middleware group from my routes, errors displays fine.
In Laravel 5.2 the web midddleware is automatically applied to your routes in routes.php so no need to apply web middleware again. It is defined in mapWebRoutes() method of RouteServiceProvider.
I am trying to get validation errors to show up in Laravel.
I have a UserController set up like so:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
//Use Request;
Use Flash;
Use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
public function store(Request $request) {
$this->validate($request, [
'email' => 'required|unique:users|email|max:255',
]);
if($this) {
$input = Request::all();
User::create($input);
return redirect('/');
}
else {
return redirect('/')->withErrors($validator);
}
}
}
In my view (layout.blade.php), I have included:
#if (count($errors) > 0)
#foreach ($errors->all() as $error)
{{!! $errors !!}}
#endforeach
#endif
To account for the route, I have:
Route::group(['middleware' => ['web']], function () {
Route::get('/', function (){
return view('home');
});
});
Unfortunately, when I enter "bad" data that shouldn't be verified, I am not seeing any error (but it is not being stored in the db, so there's that).
One other note, when the blade template is rendered, I am seeing an extra "}" bracket, which I'm not sure why that is there.
In laravel version 5.2.41, the middleware web is thrown out.
Means adding the routes inside Route::group(['middleware' => ['web']], function () { will make the validation not work.
There are a couple things wrong or that can be improved here. The store method on the UserController has a lot of weird issues. $this will always be true because objects are true in php. Also, you pass in $validator into withErrors which doesn't make sense because there's no variable validator.
public function store(Request $request) {
$this->validate($request, [
'email' => 'required|unique:users|email|max:255',
]);
User::create(Request::all());
return redirect('/');
}
The validate method will throw an Illuminate\Foundation\Validation\ValidationException if there is a validation error. This exception should be listed in the $dontReport instance variable in App\Exceptions\Handler as seen below:
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
If you have changed these values, removed, or modified the ValidatesRequest trait you may have broken this functionality.
Your error reporting code is not correct either:
#foreach ($errors->all() as $error)
{!! $errors->first() !!}
#endforeach
There are 3 changes here. First I removed the outer errors size check, this doesn't really get you anything. Next, I fixed your extra } error, the syntax for un-escaping data is {!! $errors->first() !!}. Lastly, I called ->first() this returns the first error associated with that particular field.
I think it's important to note that the validation exception will create a redirect response to the previous page. The logic for determining the previous page can be found in Illuminate\Routing\UrlGenerator::previous().
The errors block should be:
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Assuming you're using Bootstrap for the alerts.
You also don't have $validator defined. You need to do something like this:
$validator = Validator::make($request->all(), [
'email' => 'required|unique:users|email|max:255',
]);
Instead of $this->validate().
That should do it.
If it is still not working and you have tried several things like
Moving ShareErrorsFromSession::class from $middlewareGroups to $middleware
Removing the web.php to web middleware
Try modifying the request headers to
Accept: application/json
Or you can also create a new middleware that will modify the request header like this:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class ModifyAcceptHeaderMiddleware
{
public function handle(Request $request, Closure $next)
{
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
Try to remove "\Illuminate\Session\Middleware\StartSession::class" from 'middleware' in Kernel.php, it must be only in the 'web' group.
#if(count(($errors->all()) > 0))
#foreach($errors->all() as $error)
<div class="alert alert-danger">
{{$error}}
</div>
#endforeach
#endif
The problem is that withErrors() is working perfectly in this code, but withMessage() isn't.
I also tried with('message', 'Test message!'). In views file, I can retrieve withErrors using $errors variable, but if I want to retrieve withMessage, I have to use Session::get('message'). Why is $message not working?
Controller:
public function registration() {
$rules = array(...);
$validator = Validator::make(Input::all(), $rules);
if($validator->fails()) {
return Redirect::route('registration')->withErrors($validator);
}
else {
//Some code here...
return Redirect::route('registration')->withMessage('Test message!');
}
}
Template:
#extends('default.base')
#section('main')
#if(!empty($errors->all()))
<div class="alert alert-danger" role="alert">
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}
#endforeach
</ul>
</div>
#endif
#if(isset($message))
{{ $message }}
#endif
#stop
That is because errors is a special case. When creating a view, Laravel check's if there is a session variable with the name errors. If so it will then pass the contents as $errors to the view.
Illuminate\View\ViewServiceProvider#registerSessionBinder
if ($me->sessionHasErrors($app))
{
$errors = $app['session.store']->get('errors');
$app['view']->share('errors', $errors);
}
This means you either use Session::has('message') and Session::get('message') in your view or you add a View Composer that does basically the same that Laravel does with errors:
View::composer('*', function($view){
if(Session::has('message')){
$view->with('message', Session::get('message'));
}
});