So I'm trying to develop a rest API for an internal project, and I've got an issue where when the form request validation fails, it shows the @index response.
So I have two routes;
Route::get('/api/clients', 'ClientController@index');
Route::post('/api/clients', 'ClientController@store');
@index
lists all clients, @store
creates a new client and I've got a Form Request Validator on the @store
method which checks a name is provided for the client.
What I want is when the validator fails, it shows a JSON response with the validation errors. But what I think it happening, is the validation fails, so it redirects back to the same page, but the redirect is GET
instead of POST
, so it lists all the clients instead.
I know that you can set your headers so that it looks like an ajax request, in which it will show the JSON response properly, but I want it to show the JSON response regardless of whether it's ajax or not.
I've tried overriding the response
method in my validator which didn't work, I've tried setting the wantsJson
method in the validator to return true which again didn't work.
Help would be very much appreciated.
Code is below...
web.php
Route::get('/api/clients', 'ClientController@index');
Route::get('/api/clients/{client}', 'ClientController@show');
Route::post('/api/clients', 'ClientController@store');
Route::put('/api/clients/{id}', 'ClientController@update');
Route::delete('/api/clients/{id}', 'ClientController@delete');
ClientController.php
namespace App\Http\Controllers;
use App\Client;
use App\Http\Requests\ClientRequest;
class ClientController extends Controller
{
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(ClientRequest $request)
{
return Client::create([
'title' => request('title'),
'user_id' => auth()->id()
]);
}
ClientRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ClientRequest 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'
];
}
/**
* Get the failed validation response for the request.
*
* @param array $errors
* @return JsonResponse
*/
public function response(array $errors)
{
dd('exit'); // Doesn't work
}
}
You can try like this
Include use first as below in your form request
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
and then
protected function failedValidation(Validator $validator) {
throw new HttpResponseException(response()->json($validator->errors(), 422));
}
now if you try to validate then it will return like
{
"title": [
"The title field is required."
]
}
When making the request we should send header info.
Accept: application/json
Content-Type: application/json
That's it, now laravel will not redirect and send the error message as JSON.
Try this
Open app/Exceptions/Handler.php file
Include use
use Illuminate\Validation\ValidationException;
and then add method
/**
* Create a response object from the given validation exception.
*
* @param \Illuminate\Validation\ValidationException $e
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function convertValidationExceptionToResponse(ValidationException $e, $request)
{
if ($e->response) {
return $e->response;
}
return response()->json($e->validator->errors()->getMessages(), 422);
}
now you can get standard validationFailure response like ajax request
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With