Distinguish between validation errors in Laravel - validation

I'm using the validation rules in Laravel 4, which are very powerful. However, I wonder how one can distinguish between the different validations error that may occur. For example if I use the following rules:
$rules = array(
'email' => 'required|email|confirmed',
'email_confirmation' => 'required|email',
);
How can I tell what validation rule/rules that triggered the error for a certain field? Is there some way I can tell that the error was due to a missing email value, email wasn't a valid email address and/or the email couldn't be confirmed?
I quite new to laravel as I began working with it a week ago so I hope someone may shed some light on this.

The validation messages returned by the validation instance should hold the key to knowing what went wrong.
You can access the messages given by the validator object by using:
$messages = $validator->messages(); // Where $validator is your validator instance.
$messages = $messages->all()
That should give you an instance of a MessageBag object, that you can run through with a foreach loop:
foreach ($messages as $message) {
print $message;
}
And inside there, you should find your answer, i.e. there will be a message saying something like: "Email confirmation must match the 'email' field".

You can get error messages for a given attribute:
$errors = $validation->errors->get('email');
and then loop through the errors
foreach ($errors as $error) {
print $error;
}
or get all the error messages
$errors = $validation->errors->all();
then loop through the error messages
foreach ($errors as $error) {
print $error;
}
You can see more information about laravel validation here

Related

Laravel validation couldn't store value after validate and give error 500

I have a form that using ajax for update data client. In that form there is an input file. Everything is going fine except for updating the file. File is sent, it changed on storage too, but it gives error on validation and didn't change data on database.
Here is the code on the controller :
public function update(Request $request, Client $client)
{
$validatedData = Validator::make($request->all(), [
'name' => 'required|max:255',
'logo'=> 'image|file|max:100',
'level' => 'required|max:1'
]);
$validatedData['user_id'] = auth()->user()->id;
if ($validatedData->fails()){
return response()->json($validatedData->errors());
} else {
if($request->file('logo')){
if($request->oldLogo){
Storage::delete($request->oldLogo);
}
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
}
$validateFix = $validatedData->validate();
Client::where('id', $client->id)->update($validateFix);
return response()->json([
'success' => 'Success!'
]);
}
}
It gives error on line :
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
With message :
"Cannot use object of type Illuminate\Validation\Validator as array"
I use the same code that works on another case, the difference is the other not using ajax or I didn't use Validator::make on file input. I guess it's just wrong syntax but I don't really know where and what it is.
To retrieve the validated input of a Validator, use the validated() function like so:
$validated = $validator->validated();
Docs:
https://laravel.com/docs/9.x/validation#manually-creating-validators
https://laravel.com/api/9.x/Illuminate/Contracts/Validation/Validator.html
$validatedData is an object of type Illuminate\Validation\Validator.
I would say the error is earlier there as well as this line should give an error also:
$validatedData['user_id'] = auth()->user()->id;
As ericmp said, you first need to retrieve the validateddata to an array and then work with it.

Laravel Validate ->validate() method removed custom added errors?

I'm trying to use the Laravel validator to include some custom error messages before I run the validate() method. However it appears that running this method then removed any previously added errors.
I can confirm that the error message appears when I dump out the validator messages before hitting validate()
$validator = Validator::make(
$this->data,
$this->rules
);
$validator->errors()->add('meal', 'The meal field is required.');
$validator->validate();
How I can validate my data but still include the error relating to the meal?
I believe what you want to use is the after validation hook. This will allow you to add more errors like so:
$validator = Validator::make(
$this->data,
$this->rules
);
$validator->after(function ($validator) {
$validator->errors()->add(
'field', 'Something is wrong with this field!'
);
});
$validator->validate();

Laravel does not display validation errors when using $request->validate

I am not able to display the validation errors on a specific form/page when using $request->validate($rules);. Here is the controller code:
public function store(Request $request) {
$rules = [
'dummy-field' => 'required|string',
];
$params = $request->validate($rules);
// $this->validate($request, $rules); // Same result with this
dd($params);
}
In my view:
#if($errors->any())
<div class="alert alert-danger">
#foreach($errors->all() as $error)
<div>{{ $error }}</div>
#endforeach
</div>
#endif
When I submit the form (without the dummy-field) I'm properly redirected back to the previous page (If my form would pass the validation I should see the dd output), but the error messages are not displayed. I also tried dd($errors) and the ErrorBag is actually empty.
The weird thing is, using a manual Validator the error messages are properly displayed. Refactoring the controller to:
$rules = [
'dummy-field' => 'required|string',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator);
}
dd($validator);
I see the error messages.
I really can't understand this behaviour. I'm using $request->validate() for other forms in my app and I don't have any trouble.
I'm using laravel 8.
Does someone have any idea why something like this could happen?
I finally found a solution. Posting it here in case it may help someone.
The problem lies in the cookie session driver
The browser has a maximum size for a cookie (around 4k I think, but it may vary). When using $request->validate(), the redirect will put into the session both the errors and the input. If the input is long enough (in my case I had some textarea with ~300 characters text), the cookie will exceed the maximum size and the browser will ignore it, so Laravel will not be able to retrieve the errors from the session.
I can't use the file driver because my application is distributed across multiple servers beyond a load balancer, so I resolved everything using the redis driver.

Method Illuminate\Http\Request::first does not exist in laravel 6 error

I am trying to implement multiple column as unique(title,created_by). A user can not create duplicate title.
The validation give me error both in separate request class also.
The validation code is:
$created_by = auth()->user()->id;
$this->validate($request, [
'title' => 'required|max:50|unique:register_types,title,null,id,created_by,'.$created_by
]);
The code give error as "Method Illuminate\Http\Request::first does not exist"
But Validator method works successfully.
The code is:
$validator = \Validator::make($request->all(),[
'title' => 'required|max:50|unique:register_types,title,null,id,created_by,'.$created_by
]);
if ($validator->fails()) {
return $validator->errors();
}
I want to use first clean code pattern. How is it possible ?
I got my problem.
Some days ago, I have added a condition at render method in handler class:
elseif ($exception instanceof ValidationException) {
return $exception->first();
}
Solution:
At this time, just I blocked this condition.
Problem solved.

Laravel 5: Validating Edits In-Place

I had previously asked a question here in regards for setting up in-place editing with Laravel 5 and AJAX. I hadn't updated it because I had managed offline to figure out what was wrong with it.
While the table is capable of editing user rows in-place, I'm now trying to add validation on top of it, intending on utilizing Laravel's built-in validator. However, for some reason it doesn't seem to be working. When I try to pass in the failed validator back through the JSON, it spits out every possible error I'm checking for. It's as if the validator is treating every input as empty, which doesn't make sense, as the rest of the function is clearly taking in the inputs as intended.
The code snippets in my previous question are still mostly relevant, but there have been updates to HomeController.php, as can be seen below:
public function updateTable(Users $users){
$user = request()->input('user');
$first_name = request()->input('first_name');
$last_name = request()->input('last_name');
$validator = Validator::make(request()->all(), [
'firstName' => 'required|alpha',
'lastName' => 'required|alpha'
], [
'firstName.required' => 'You need to give a first name!',
'firstName.alpha' => 'A first name can only contain letters!',
'lastName.required' => 'You need to give a last name!',
'lastName.alpha' => 'A last name can only contain letters!'
]);
if ($validator->fails()) {
return response()->json($validator, 404);
}
$employees->editUser($user, $first_name, $last_name);
return response()->json($user);
}
So I realized the issue was twofold. First, what I was trying to return when the validator failed was incorrect. Rather than simply passing the whole validator, I needed to simply pass its messages, like so:
if ($validator->fails()) {
return response()->json($validator->messages(), 404);
}
The second issue actually had to do with calling "request()->all()". I had assumed the array obtained would have worked, but for some reason it didn't. When I created a new array based on the values in "request()" it was able to get the validator results I was expecting.

Resources