As the question states. I am using the validation method where the Rules and Custom Messages are placed in the Http/Requests folder. However, I want to get the messageErrorBag in Laravel I don't have any problems if I am using the code below I can easily add my own variables to be passed together with the validator message bag.
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
However, if using the code below. I cannot do it since Laravel already handles the error return as per documentation.
public function store(StoreBlogPost $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
}
My question how can I do it? before it redirects back with the error message bag.? Is it possible
If you use StoreBlogPost in Controller , it automatically returns messages but if you want your messages in body of controller you should add validator to your controller body and use this code:
if ($validator->fails())
{
foreach ($validator->messages()->getMessages() as $field_name => $messages)
{
var_dump($messages); // messages are retrieved (publicly)
}
}
hope it helps
Related
So i'm working on validating a form's inputs using the following code:
$request->validate([
'title' => 'bail|required|max:255',
'body' => 'required',
]);
So basically, there are two fields in the form, a title and a body and they have the above rules. Now if the validation fails I want to catch the error directly in the controller and before being redirected to the view so that I can send the error message as a response for the Post request. What would be the best way to do it?
I understand that errors are pushed to the session but that's for the view to deal with, but i want to deal with such errors in the controller itself.
Thanks
If you have a look at the official documentation you will see that you can handle the input validation in different ways.
In your case, the best solution is to create the validator manually so you can set your own logic inside the controller.
If you do not want to use the validate method on the request, you may create a validator instance manually using the Validator facade.
Here a little example:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'bail|required|max:255',
'body' => 'required',
]);
// Check validation failure
if ($validator->fails()) {
// [...]
}
// Check validation success
if ($validator->passes()) {
// [...]
}
// Retrieve errors message bag
$errors = $validator->errors();
}
For someone who wants to know how to get validation errors after page redirection in the controller:
$errors = session()->get('errors');
if ($errors) {
//Check and get the first error of the field "title"
if ($errors->has('title')) {
$titleError = $errors->first('title');
}
//Check and get the first error of the field "body"
if ($errors->has('body')) {
$bodyError = $errors->first('body');
}
}
$errors will contain an instance of Illuminate/Contracts/Support/MessageBag
You can read more on the API here: https://laravel.com/api/8.x/Illuminate/Contracts/Support/MessageBag.html
Note: I have tested it in Laravel 8, it should work on Laravel 6+ if you get the MessageBag from the session
I have a problem with the laravel validation.
Call to a member function fails() on array
Symfony\Component\Debug\Exception\FatalThrowableError thrown with message "Call to a member function fails() on array"
Stacktrace:
`#0 Symfony\Component\Debug\Exception\FatalThrowableError in
C:\laragon\www\frontine\app\Http\Controllers\authController.php:37
public function postRegister(Request $request)
{
$query = $this->validate($request, [
'user' => 'string|required|unique:users|min:4|max:24',
'email' => 'email|string|required|unique:users',
'pass' => 'string|required|min:8',
'cpass' => 'string|required|min:8|same:pass',
'avatar' => 'image|mimes:jpeg,jpg,png|max:2048',
]);
if ($query->fails())
{
return redirect('/registrar')
->withErrors($query)
->withInput();
}
}
The error is because what the ->validate() method returns an array with the validated data when applied on the Request class. You, on the other hand, are using the ->fails() method, that is used when creating validators manually.
From the documentation:
Manually Creating Validators
If you do not want to use the validate method on the request, you may
create a validator instance manually using the Validator facade. The
make method on the facade generates a new validator instance:
use Validator; // <------
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [ // <---
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
// Store the blog post...
}
}
The ->fails() is called in the response of the Validator::make([...]) method that return a Validator instance. This class has the fails() method to be used when you try to handled the error response manually.
On the other hand, if you use the validate() method on the $request object the result will be an array containing the validated data in case the validation passes, or it will handle the error and add the error details to your response to be displayed in your view for example:
public function store(Request $request)
{
$validatedData = $request->validate([
'attribute' => 'your|rules',
]);
// I passed!
}
Laravel will handled the validation error automatically:
As you can see, we pass the desired validation rules into the validate
method. Again, if the validation fails, the proper response will
automatically be generated. If the validation passes, our controller
will continue executing normally.
What this error is telling you is that by doing $query->fails you're calling a method fails() on something (i.e. $query) that's not an object, but an array. As stated in the documentation $this->validate() returns an array of errors.
To me it looks like you've mixed a bit of the example code on validation hooks into your code.
If the validation rules pass, your code will keep executing normally;
however, if validation fails, an exception will be thrown and the
proper error response will automatically be sent back to the user. In
the case of a traditional HTTP request, a redirect response will be
generated, [...]
-Laravel Docs
The following code should do the trick. You then only have to display the errors in your view. You can read all about that, you guessed it, in... the docs.
public function postRegister(Request $request)
{
$query = $request->validate($request, [
'user' => 'string|required|unique:users|min:4|max:24',
'email' => 'email|string|required|unique:users',
'pass' => 'string|required|min:8',
'cpass' => 'string|required|min:8|same:pass',
'avatar' => 'image|mimes:jpeg,jpg,png|max:2048',
]);
}
I'm trying to validate a request like this.
public function reply(CustomRequest $request)
{
$request->validated();
}
The issue is that it will automatically redirect to the previous page if the validation fails. Whereas I want to do some custom logic.
For example
if($request->validation->fails()) {
// Do things
}
But I can't find a way to do this without passing in validation rules, whereas I want to use the rules from the "CustomRequest" class.
Using the Validator::make(), you can redirect your customised stuff.
Here is an example how you can return the first error in the ErrorBag:
$validator = Validator::make($request->all(), [
'field' => ['required']
]);
if ($validator->fails()) {
return redirect()->back()->with('custom_error', $validator->errors()->first());
};
Hi guys I'm working on API but I need to validate some data at backend, in this case, we only need a postman to send parameters and headers.
All is working fine now but I need more useful data in each request, Laravel has by default a Validator Form Request Validation, but I donĀ“t know how to use at API side.
I need to send the error message in JSON to Postman.
I found two options, one, make validations into a controller but seems to much code and the other make a php artisan make:request StoreObjectPost and then import the request into the controller and change the request of the store method, which one do you recommend, Ty!
You could instantiate the validator yourself like this:
$validator = Validator::make($request->all(), [
'name' => 'min:5'
]);
// then, if it fails, return the error messages in JSON format
if ($validator->fails()) {
return response()->json($validator->messages(), 200);
}
$PostData = Input::all();
$Validator = Validator::make(array(
'name' => $PostData['name']
), array(
'name' => 'required'
));
if ($Validator->fails()) { //if validator is failed
return false;
} else {
// do some thing here
}
Hope this may help you
You should override response(array $errors) method of FormRequest.
public function response(array $errors)
{
//Format your error message
if ($this->expectsJson()) {
return new JsonResponse($errors, 422);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
I prefer the second option. We will be able to keep our controller clean that way, even when we use many validations for the data or using custom error message in the validation
I've created a simple contact form in Laravel 5, using the Request object and a Validator object to check my input for errors.
The form in my view is coded in HTML, rather than the Laravel Form object, which isn't included by default in Laravel 5.
I need to set up my form so that if a validation rule fails, the user's input is flashed to the session so it doesn't disappear when the page redirects. I was able to accomplish this by putting a $request->flash() in the POST controller, before the validation code.
However, I do not want the data to be flashed (i.e, the form should be reset) if the validation passes and the form is successfully emailed. There's no apparent way for me to accomplish this in the $this->validate block, since Laravel helpfully handles the redirects automatically.
How can I tell Laravel to flash the form data ONLY if there is a validation error?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class ContactController extends Controller
{
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
return view('contact');
}
/**
* Store a newly created resource in storage.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
// Flash current input in case the validator fails and redirects
$request->flash();
// Validate the form request, redirect on fail
$this->validate($request, [
'name' => 'required',
'email' => 'required|email',
'subject' => 'required',
'message' => 'required|min:5',
]);
// Generate email from template and send
\Mail::send('emails.feedback',
array(
'name' => $request->get('name'),
'email' => $request->get('email'),
'user_message' => $request->get('message'),
'subject' => $request->get('subject')
), function ($message) use ($request) {
$message->from(\Config::get('site.from_email'));
$message->to(\Config::get('site.contact_email'), 'Admin');
$message->subject(\Config::get('site.name') . ': ' . $request->get('subject'));
});
// Redirect to Contact route with success message
return \Redirect::route('contact')
->with('message', 'Thanks for contacting us!');
}
}
?>
If anybody like me didn't know how to get the old values and end up here somehow, here it goes:
<input value="{{ old('var_name') }}">
I don't see you needing to access the session data when Laravel provides you helpers like this.
Hope to have helped, have a nice day. =)
Just remove the following line of code:
$request->flash();
Laravel will take care of that for you by flashing the data on failed validation. The following method gets called on failed validation:
/**
* Create the response for when a request fails validation.
*
* #param \Illuminate\Http\Request $request
* #param array $errors
* #return \Illuminate\Http\Response
*/
protected function buildFailedValidationResponse(Request $request, array $errors)
{
if ($request->ajax() || $request->wantsJson()) {
return new JsonResponse($errors, 422);
}
return redirect()->to($this->getRedirectUrl())
->withInput($request->input()) // <-- Flashes inputs
->withErrors($errors, $this->errorBag()); // <-- Flashes errors
}
This is the trait used in your controller for validating the request and it's located at Illuminate/Foundation/Validation, name is ValidatesRequests. Check it to clarify yourself.
Alternatively, you may do it manually if you want for any reason, check the documentation.
To restore the old value if validation fails the entered data will display the view
value="{{ (old('title')) ? old('title') : $data->title}}