Laravel Validation Error Message required_if not working - php

I am validating a form using Laravel 5.2
using validation check required_if for input youtube-embed. validation takes place successfully but the custom error message does not work. Here is the code maybe some one can take a look.
$messages = [
'youtube-embed.required_if' => 'Please paste in your youtube embed code',
];
$this->validate($request, [
'youtube-embed' => 'required_if:youtube,on',
]);
This is the error message that laravel is returning instead of my custom error:
The youtube-embed field is required when youtube is on.

Try this:
$this->validate($request,
['youtube-embed' => 'required_if:youtube,on',],
['required_if' => 'Please paste in your youtube embed code',]
);
Basically you can pass your custom messages as third parameter in validate function.

/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
'payout_method' => 'required:in,bankTransfer,paypal',
'paypal_email' => 'required_if:payment_type,paypal|email',
'receiver' => 'required_if:payment_type,bankTransfer|max:45',
'iban' => 'required_if:payment_type,bankTransfer|max:45|iban',
'bic' => 'required_if:payment_type,bankTransfer|max:15|bic',
];
return $rules;
}
/**
* Get the error messages for the defined validation rules.
*
* #return array
*/
public function messages()
{
return [
'payout_method.required' => trans('validation.attributes.payout_type_required'),
'paypal_email.required_if' => trans('validation.attributes.paypal_email_required'),
'paypal_email.email' => trans('validation.attributes.paypal_email_invalid'),
'iban.required_if' => trans('validation.attributes.bank_account_required'),
'bic.required_if' => trans('validation.attributes.bank_swift_required'),
'iban.iban' => trans('validation.attributes.bank_account_invalid'),
'bic.bic' => trans('validation.attributes.bank_swift_invalid'),
];
}
what i can do in this case? Laravel return 'The paypal email field is required.' for other fields this work, only not work with required_if

If your'e using the Request class:
public function messages()
{
return [
'youtube-embed.required' => 'Your custom message here.',
];
}
Works on Laravel 7

Related

How to define field specific error message or overwrite the default one for a custom validation rule used in a FormRequest in Laravel 5.5

I have created a custom validation rule and I am using it to validate a data field in a FormRequest.
However, I would like to use a different message for this field and not the default message that is set in the Rule's message() method.
So, I tried using the method messages() inside of the FormRequest using a key of the field name and the rule (in snake case)
public function rules()
{
return [
'clients' => [
new ClientArrayRule(),
],
];
}
public function messages()
{
return [
'clients.client_array_rule' => "clients should be a valid client array"
];
}
The error message did not change, I investigated a little inside the code of the validator and I found out that for custom rules, it uses the method validateUsingCustomRule that doesn't seem to care about custom messages.
Any ideas on how it can be overwritten or what would be the best way to do it?
For custom message on Laravel:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'username' => 'required',
'password' => 'required',
'email' => 'required',
'age' => 'required|gte:4',
];
}
/**
* Get the error messages for the defined validation rules.
*
* #return array
*/
public function messages()
{
return [
'username.required' => 'Custom message',
'password.required' => 'Custom message',
'email.required' => 'Custom message',
'age.required' => 'Custom message',
'age.gte' => 'Custom message'
];
}

Laravel: Custom validation messages in Custom Form Requests

I am trying to keep my controller clean and move the custom request validation in to a separate class as:
public function register(RegisterUserRequest $request)
and in there define all the usual functions, such as
public function rules(),
public function messages(), and
public function authorize()
However, the frontend is expecting the following data to display:
title (title related to the validation error message), description (which is the the actual validation error message), and status (=red, yellow etc)
How can I actually customise the response of the request?
Something like this, does not seem to be working:
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
$response = new Response(['data' => [],
'meta' => [
'title' => 'Email Invalid'
'description' => '(The error message as being returned right now)',
'status' => 'red'
]);
throw new ValidationException($validator, $response);
}
Any ideas?
you can do this by making request in laravel as the following :
php artisan make:request FailedValidationRequest
this command will create class called FailedValidationRequest in
App\Http\Request directory and you cab write your rules inside this class as the following:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class FailedValidationRequest 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 [
'title' => 'required'
'description' => 'required',
'status' => 'required|numeric'
];
}
}
and if you want to customize the error message you can download the language you want from this link using composer:
https://packagist.org/packages/caouecs/laravel-lang
and write the language you want by copying the languge folwder to the lang directory in your resource folder.
'custom' => [
'title' => [
'required' => 'your custom message goes here',
],
'decription' => [
'required' => 'your custom message goes here',
],
],

Send custom response from validator in Laravel

I have a register user route which takes name , email and password. It works perfectly fine if the data is correct i.e. unique email and params are present, but if the user is already registered then Laravel sends auto error message in its own format. I want return format to be consistent in case of success or failure.
Successful Register return data:
{
"status": "success",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjUsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6ODAwMC9hcGkvYXV0aC9yZWdpc3RlciIsImlhdCI6MTUyMTI3NTc5MiwiZXhwIjoxNTIxMjc5MzkyLCJuYmYiOjE1MjEyNzU3OTIsImp0aSI6Ik1wSzJSYmZYU1dobU5UR0gifQ.fdajaDooBTwP-GRlFmAu1gtC7_3U4ygD1TSBIqdPHf0"
}
But in case of error it sends data in other format.
{"message":"The given data was invalid.","errors":{"email":["The email has already been taken."]}}
I want both of them to be consistent. Success return data is fine. But i want to customize data if failure occurs. Something like this:
{"status":"error","message":"The given data was invalid.","errors":{"email":["The email has already been taken."]}}
Basically, I need status param to be coming with every response.
Also, I had one query while using Postman the output was pure HTML when error occurred the HTML page was default Laravel Page on the other hand when angular sends the same request the error is json format which i just pasted above.
Since angular is getting JSON respose in any case it is fine for me. But why didn't postman showed me that response.
Register Controller:
public function register(RegisterRequest $request)
{
$newUser = $this->user->create([
'name' => $request->get('name'),
'email' => $request->get('email'),
'password' => bcrypt($request->get('password'))
]);
if (!$newUser) {
return response()->json(['status'=>'error','message'=>'failed_to_create_new_user'], 500);
}
return response()->json([
'status' => 'success',
'token' => $this->jwtauth->fromUser($newUser)
]);
}
Register Request Handler:
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'required | email | unique:users,email',
'password' => 'required'
];
}
If I understand you correctly, you always get the error-response without the 'status' key.
What happens with your current code, are a couple of things:
RegisterController#register(RegisterRequest $request) is called by a route
Laravel sees you use the RegisterRequest class as an argument, and will instantiate this class for you.
Instantiating this class means it will directly validates the rules.
If the rules are not met, laravel directly responds with the errors found.
This response will always be in laravel's default 'layout' and the code stops there.
Conclusion: Your code is not even triggered when your validation rules are not met.
I've looked into a solution and came up with this:
public function register(Illuminate\Http\Request $request)
{
//Define your validation rules here.
$rules = [
'name' => 'required',
'email' => 'required | email | unique:users,email',
'password' => 'required'
];
//Create a validator, unlike $this->validate(), this does not automatically redirect on failure, leaving the final control to you :)
$validated = Illuminate\Support\Facades\Validator::make($request->all(), $rules);
//Check if the validation failed, return your custom formatted code here.
if($validated->fails())
{
return response()->json(['status' => 'error', 'messages' => 'The given data was invalid.', 'errors' => $validated->errors()]);
}
//If not failed, the code will reach here
$newUser = $this->user->create([
'name' => $request->get('name'),
'email' => $request->get('email'),
'password' => bcrypt($request->get('password'))
]);
//This would be your own error response, not linked to validation
if (!$newUser) {
return response()->json(['status'=>'error','message'=>'failed_to_create_new_user'], 500);
}
//All went well
return response()->json([
'status' => 'success',
'token' => $this->jwtauth->fromUser($newUser)
]);
}
Now, not conforming your validation rules still triggers an error, but your error, and not laravel's built-in error :)
I hope it helps!
In Laravel 8 I added my custom invalidJson with the "success": false:
in app/Exceptions/Handler.php:
/**
* Convert a validation exception into a JSON response.
*
* #param \Illuminate\Http\Request $request
* #param \Illuminate\Validation\ValidationException $exception
* #return \Illuminate\Http\JsonResponse
*/
protected function invalidJson($request, ValidationException $exception)
{
return response()->json([
'success' => false,
'message' => $exception->getMessage(),
'errors' => $exception->errors(),
], $exception->status);
}
This is what i came up with:
function validate(array $rules)
{
$validator = Validator::make(request()->all(), $rules);
$errors = (new \Illuminate\Validation\ValidationException($validator))->errors();
if ($validator->fails()) {
throw new \Illuminate\Http\Exceptions\HttpResponseException(response()->json(
[
'status' => false,
'message' => "Some fields are missing!",
'error_code' => 1,
'errors' => $errors,
], \Illuminate\Http\JsonResponse::HTTP_UNPROCESSABLE_ENTITY));
}
}
Create a helper directory (App\Helpers) and add it into a file. don't forget to add that into your composer.json
"autoload": {
"files": [
"app/Helpers/system.php",
],
},
Now you can call validate() in your controllers and get what you want:
validate([
'email' => 'required|email',
'password' => 'required|min:6|max:32',
'remember' => 'nullable|boolean',
'captcha' => 'prod_required|hcaptcha',
]);

How to display custom vaildation error messages for API requests?

try{
$request->validate([
'aadhar' => 'required|digits:12|numeric',
'name' => 'required|string|max:511',
'dob' => 'required|date_format:Y-m-d',
'email' => 'required|email|max:255',
'address' => 'required|string',
'insuranceid' => 'required|digits_between:1,15|integer',
'password' => 'required|min:59|max:60',
]);
}
catch(Exception $error){
$message = $error->getMessage();
$status_code=400;
return response()->json(["message" => $message,"status_code" => $status_code]);
}
This is my piece of code for the validation of the request parameters sent to an API. The documentation gives details only about custom error messages in case of a form request.
The validation errors give the default message "The given data was invalid" but I would like to know which of the parameter was invalid. How do I give custom validation error messages for API requests validation?
First of all, to decouple your code, you could use a Form Request class. From the docs:
For more complex validation scenarios, you may wish to create a "form
request". Form requests are custom request classes that contain
validation logic.
This class contains two methods:
1 - rules, the place where you specify your rules, it should return an array of rules.
2 - authorize that return a boolean,this method control who is allowed to perform this request. By default is set to false, so every call will be rejected.
So, in your case, it should be something like this:
First, create your custom Request class executing this artisan command in your console:
php artisan make:request CreateCustomObjectRequest
This wil create a new class under app/Http/Requests:
class CreateCustomObjectRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
// Implement here your Auth validation, something like:
return auth()->check();
// or just return "true" if you want to take care of this anywhere else.
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'aadhar' => 'required|digits:12|numeric',
'name' => 'required|string|max:511',
'dob' => 'required|date_format:Y-m-d',
'email' => 'required|email|max:255',
'address' => 'required|string',
'insuranceid' => 'required|digits_between:1,15|integer',
'password' => 'required|min:59|max:60',
];
}
}
And then, in your controller, instead of inject a regular Request object, we are gonna use this custom Request object:
use App\Http\Requests\CreateCustomObjectRequest;
// ...
public function store(CreateCustomObjectRequest $request)
{
// the rest of your controller logic.
}
Now, the part you are really interested in. To return errors in a json way you should add the next header when making a request:
Accept: Application/json
This header will tell Laravel that the output should be a json response, so it will convert it to json. Note that this will only work with the validation rules and when returning objects like return $someObject. To more further customization you shoud use something like:
return response()->json(['data' => $someObject], 200);
$validator = Validator::make($request->all(), [
'password' => [
'required',
'confirmed',
'between:8,55'
]
]);
if ( $validator->fails() ) {
return response()->json( [ 'errors' => $validator->errors() ], 400 );
}

Validation - Returning the first error for an AJAX response

I'm probably over complicating things where it's not needed, but I have a form that is submitted via AJAX and then validated. I'm trying to return the first error that occurs, but I can only ever seem to fetch validation.required which of course is useless to me; I can't tell the user which field failed and nor can I translate an appropriate error message.
What gives? How can I fetch a human-friendly error message and return it back as a JSON response?
Here's what I've got going so far... The biggest how-do-I is fetching the attribute name for the error message, but maybe there's a far easier way to manage this altogether...
/**
* Adds a new post to the system
*
* #param Request $request
* #return json
*/
public function store(Request $request)
{
// run validation
if(!empty($validator = $this->validate($request)))
{
return response()->json(trans('global/'.$validator->first(), ['attribute' => 'how to get attribute?!?!']), 400);
}
// some other logic...
}
/**
* Validates a post add or post update request
*
* #access private
* #param Request $request
* #return mixed
*/
private function validate(Request $request)
{
// set-up validation rules
$validator = Validator::make($request->all(), [
'username' => 'max:255|required',
'email' => 'email',
'service' => 'numeric|required',
]);
$validator->setAttributeNames([
'username' => "Username",
'service' => "Service",
]);
// run validation
if($validator->fails())
{
return $validator->errors();
}
return true;
}
Use code above in your controller store method and do not override validate method:
$rules = [
'username' => 'max:255|required',
'email' => 'email',
'service' => 'numeric|required',
];
$attributes = [
'username' => "Username",
'service' => "Service",
];
$this->validate($request, $rules, [], $attributes);
It will automatically returns errors json if validation fails.
Errors example:
{"username":["The Username field is required."],"service":["The Service field is required."]}

Categories