Laravel Custom Error Validation JSON Response Object to Array - php

I try to create an API for the registration form if a user does not fill the required field. The validator show error in object format but i need json response in an array format.
$validator = Validator::make($request->all(), [
'name' => 'required',
'mobile' => 'required',
'address' => 'required',
]);
if ($validator->fails()) {
return response()->json(['error'=>$validator->errors()], 401);
}
Current output is
{
"error": {
"name": [
"The name field is required."
],
"mobile": [
"The mobile field is required."
],
"address": [
"The addressfield is required."
]
}
}
Expected output
{
"error": [
"The name field is required.",
"The mobile field is required.",
"The address field is required."
]
}

Correct answer is this one:
$err = array();
foreach ($validator->errors()->toArray() as $error) {
foreach($error as $sub_error){
array_push($err, $sub_error);
}
}
return ['errors'=>$err];
the inner foreach is added because maybe more than one validation condition fails for an input( like : password is too short & too weak).
and Mayank Pandeyz's answer for loop won't iterate because until we add toArray() to the end of $validator->errors().

For getting the expected result, iterate the $validator->errors() using foreach() loop and push all the values in an array and return that array like:
$err = array();
foreach ($validator->errors() as $error)
{
array_push($err, $error);
}
return response()->json(['error'=>$err], 401);

Related

laravel 8, how to get individual errors message in array based on the field names instead of this default array

I have a contact form, with some field and i want to get error message based on the form field, i.e the error message for name, email, phone, subject and message
Here is what I get here:
XHRPOSThttp://127.0.0.1:8000/save
[HTTP/1.1 200 OK 137ms]
success false
errors [ "The name field is required.", "The email field is required.", "The phone field is required.", "The subject field is required.", "The description field is required." ]
because of this line in controller
$validator->errors()->all()
but I want the error message to be like:
errors:object{name:""The name field is required."
email:"The email field is required.", ...}
the controllers look like
$validator = Validator::make($request->all(), [
'name' => 'required|max:60',
'email' => 'required|email',
'phone' => 'required|min:10|numeric',
'subject' => 'required|max:100',
'description' => 'required|max:250',
]);
if ($validator->fails()) {
return response()->json([
'success' => false, 'errors' =>$validator->errors()->all()
]);
}
You probably want to use the default Laravel validation function (available in all controllers), which handles this output automatically:
// SomeController.php
$this->validate($request, [
'name' => 'required|max:60',
// ...
]);
When the validation fails, a ValidationException is thrown which should be automatically handled in your exception handler.
You can try with using FormRequest for validation and custom messages.
https://laravel.com/docs/8.x/validation#creating-form-requests
use Illuminate\Support\Facades\Validator;
$exampleRequest = new ExampleRequest();
$validator = Validator::make($request->all(), $exampleRequest->rules(), $exampleRequest->messages());
if($validator->fails()){
return response()->json($validator->errors(), 422);
}
This will return JSON response (for an API in this case):
{
"name": [
"First name is required."
]
}
For given rules and messages in ExampleRequest:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
// 'name' => 'required',
];
}
public function messages()
{
return [
'name.required' => 'First name is required.'
];
}

How to convert Laravel 7 error json to this new json

Hello, I would like to know if it is possible for me to transform Laravel's error json into this new json.
I'm using Laravel 7
{
"message": "The given data was invalid.",
"errors": {
"email": [
"email is already in use"
],
"username": [
"username is already in use"
]
}
}
to
{
"message": "The given data was invalid.",
"errors": {
"email": "email is already in use",
"username": "username is already in use"
}
}
Inside of your controller if you validate your POST request with the Validator facade you can convert the errors into a collection and map over them.
use Illuminate\Support\Facades\Validator;
// Faking the Request array & Commenting out to fail request
$input = [
// 'username' => 'username',
// 'password' => 'password',
];
$validator = Validator::make((array) $input, [
'username' => 'required|unique|string',
'password' => 'required|string',
]);
if ($validator->fails()) {
$formatted = collect($validator->errors())->map(function ($error) {
return $error[0];
});
return response()->json([
'message' => 'The given data was invalid.',
'errors' => $formatted,
], 422);
}
I'd propose a different approach to the problem.
In you User model you could add a class method called ValidationBook.
public static function ValidationBook($except = [], $append = [])
{
$book = ['rules' => [], 'messages' => []];
$book['rules'] = [
'user.email' => 'required|email|unique:users,email',
'user.password' => 'required|min:8',
'user.password_confirmation' => 'required|min:8|same:user.password',
];
$book['messages'] = [
'user.email.required' => 'The email is required',
'user.email.email' => 'The email must be a valid email address.',
'user.email.unique' => 'This email is already in use.',
'user.password.required' => 'A password is required.',
'user.password.min' => 'Password musst have at least 8 characters',
'user.password_confirmation.required' => 'The password confirmation is required.',
'user.password_confirmation.same' => 'Passwords doesn't match',
];
if (!empty($except)) {
$except = array_flip($except);
$book['rules'] = array_diff_key($book['rules'], $except);
}
if (!empty($append))
$book = array_merge_recursive($book, $append);
return $book;
}
Then, in the controller that receives the request you can simply do:
$vb = User::ValidationBook();
$vb["rules"]["user.client_secret"] .= $request->input("user")["client_id"];
$data = $request->validate($vb["rules"], $vb["messages"]);
Notice that you could define each of the errors, and if something has more than one issues, the response will send all the rules that failed.

How to create a laravel API for multiple array of an object

I am creating a laravel multiple array of an object API but my controller gives an error
Below is the request
[
{
"ProductTitle": "Clarks Men's Tilden Cap Oxford shoe",
"ProductColor": "Dark tan leather",
"ProductImage": "imageurl"
}
,
{
"ProductTitle": "Clarks Men's Tilden Cap Oxford shoe",
"ProductColor": "Dark tan leather",
"ProductImage": "imageurl"
}
]
My API store controller is as below
public function store(Request $request)
{
$input = $request;
$validator = Validator::make($input, [
'ProductTitle' => 'required',
'ProductColor' => 'required',
'ProductImage' => 'required'
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$cartdetails=shopCartDetails::create($request->all());
return $this->sendResponse( $cartdetails,'Great success! cart details posted');
}
Am getting error
Argument 1 passed to Illuminate\Validation\Factory::make() must be
of the type array, object given,
the results have now changed to
{
"success": false,
"message": "Validation Error.",
"data": {
"ProductTitle": [
"The product title field is required."
],
"ProductColor": [
"The product color field is required."
],
"ProductImage": [
"The product image field is required."
]
} }
seems it gets only one array
You are passing the full request object instead of the values to your validator
Validator::make($request->all()...
You can validate arrays (of objects) using * like this
$validator = Validator::make($request->all(), [
'*.ProductTitle' => 'required',
'*.ProductColor' => 'required',
'*.ProductImage' => 'required'
]);

Validating the key in the data in Lumen

I am validating a request that looks like this:
{
"data": [
{
"id": 1,
"name": "Foo",
"values":{
"val1":"This",
"99":"That"
}
}
]
}
Here is my custom messages:
$messages = [
'data.id'=>'is required',
'data.name'=>'is required',
'data.values'=>'must be array',
'data.values.*'=>'must be numeric'
];
My validation rule is this:
$this->validate(
$request,
[
'data'=>'required|array',
'data.*.id'=>'required|numeric',
'data.*.name'=>'required',
'data.*.values'=>'array',
'data.*.values.*'=>'numeric'
],
$messages
);
The rule validates the values in the "values" array. I want to validate the key in the "values" array [val1, 99] instead.
Write a custom validation rule for data.*.values:
'data.*.values' => function($attribute, $value, $fail) {
//$value contains your array of $key => $value pairs for you to loop through
if( /* doesn't pass your rules */){
return $fail('custom validation failed');
}
},

Customize a Json object to follow a specific format

In my Laravel API, email validation error response comes like this...
{
"status": 409,
"message": {
"emailAddress": [
"A user with email: my#email.com already exists."
]
}
}
The message value comes from this : $validator->messages();
Now, what I want is to get the error response like this json format
{
"status": 409,
"message": "A user with email: my#email.com already exists"
}
How to get this done by going inside $validator->messages(); ?
If you only want to return the first error to your user, you can handled that by using the MessageBag as a Collection, like so:
$validator = Validator::make($request->input(), [
"email" => "...",
"password" => "..."
]);
if ($validator->fails()) {
$firstError = $validator->messages()->first();
return response()->json(["status" => 409, "message" => $firstError], 409);
}
For larval 5.6 and above you can use below solution.
Edit file under app/Exceptions/Handler.php and add following files
protected function convertValidationExceptionToResponse(ValidationException $e, $request) {
if ($e->response) {
return $e->response;
}
$errors = $e->validator->errors()->getMessages();
if ($request->expectsJson()) {
return response()->json(["errors" => $this->error_to_json($errors)], 422);
}
return redirect()->back()->withInput(
$request->input()
)->withErrors($errors);
}
protected function error_to_json($errors) {
$json_errors = $errors;
$new_errors = array();
foreach ($json_errors as $key => $value) {
$new_errors[$key] = $value[0];
}
return $new_errors;
}
Hope this help you:
$validator = Validator::make($request->all(), [
'email' => 'required|emails|exists:users',
]);
if ($validator->fails()) {
return response()->json(['status' => 409, 'message' => "A user with email: ' . $request->email . ' already exists"], 200);
}

Categories