I am working with L5 Form Requests and don\'t I just love Taylor! Well, I am doing some AJAX requests and I still want to retain my form requests. The problem is that in the
Currently accepted answer no longer works so i am giving an updated answer.
In the revelent FormRequest use failedValidation function to throw a custom exception
// add this at the top of your file
use Illuminate\Contracts\Validation\Validator;
use App\Exceptions\MyValidationException;
protected function failedValidation(Validator $validator) {
throw new MyValidationException($validator);
}
Create your custom exception in app/Exceptions
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Contracts\Validation\Validator;
class MyValidationException extends Exception {
protected $validator;
protected $code = 422;
public function __construct(Validator $validator) {
$this->validator = $validator;
}
public function render() {
// return a json with desired format
return response()->json([
"error" => "form validation error",
"message" => $this->validator->errors()->first()
], $this->code);
}
}
This is the only way I found. If there is a better approach please leave a comment.
This works in laraval5.5, I don't think this will work in laravel5.4 but i am not sure.
Found the answer here: Laravel 5 custom validation redirection
All you need to do is to add a response() method in your form request and it will override the default response. In your response() you can redirect in whatever fashion you want.
public function response(array $errors)
{
// Optionally, send a custom response on authorize failure
// (default is to just redirect to initial page with errors)
//
// Can return a response, a view, a redirect, or whatever els
return response()->json(['Result'=>'ERROR','Message'=>implode('<br/>',array_flatten($errors))]); // i wanted the Message to be a string
}
UPDATE on L5.5+
This error and the accepted solution was for L5.4. For L5.5, use Ragas' answer above (failedValidation() approach)
If you are in laravel 5+ you can easily achieve this, by overriding the invalid() or invalidJson() method in the App/Exceptions/Handler.php file
In my case, I was developing an API and the api responses should be in a specific format, so I have added the following in the Handler.php file.
/**
* 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([
'code' => $exception->status,
'message' => $exception->getMessage(),
'errors' => $this->transformErrors($exception),
], $exception->status);
}
// transform the error messages,
private function transformErrors(ValidationException $exception)
{
$errors = [];
foreach ($exception->errors() as $field => $message) {
$errors[] = [
'field' => $field,
'message' => $message[0],
];
}
return $errors;
}
This is inspired by this post and the answer by Shobi. Why not keep the transformErrors function from the Shobi's answer and simply modify the render function inside Handler.php? An example would look like:
/**
* Render an exception into an HTTP response.
*
* @param Request $request
* @param Exception $exception
* @return Response
*
* @throws Exception
*/
public function render($request, Exception $exception)
{
if ($exception instanceof ValidationException) {
return response()->json([
'code' => $exception->status,
'error' => $exception->getMessage(),
'message' => $this->transformErrors($exception)
], $exception->status);
}
return parent::render($request, $exception);
}
This makes invalidJson function redundant and allows to add more fine-grained differentiation of custom json responses on each type of exception.
Tested on Laravel 6.2