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