5

I am using Laravel 5.4. I have a custom form request class where I have my validation rules and messages and I use it in my controller like following :

public function store(CustomFormRequest $request)
{
  //
}

I am using ajax to send the request and when there is any validation error, Laravel throws an error with an HTTP response with a 422 status code including a JSON representation of the validation errors.

But I don't want that. Instead, inside my controller's method, I want to find out if there is any validation error and if there is any then I want to return a response with some additional data along with the validation messages, like this:

// Inside my Controller
public function store(CustomFormRequest $request)
{
   if ($validator->fails())
   {
        $errors = $validator->errors();

        return response()->json(array('status' => 2, 'msg' => $errors->all() ));
    }
}

Could you please help ? Thanks in advance.

4 Answers 4

4

The easiest way to do this would be to override the response() method for the Form Request class.

To do this you can simply add something like the following to your class:

public function response(array $errors)
{
    if ($this->expectsJson()) {
        return new JsonResponse(['status' => 2, 'msg' => $errors], 422);
    }

    return parent::response($errors);
}

Don't for get to import Illuminate\Http\JsonResponse

Hope this helps!

Sign up to request clarification or add additional context in comments.

5 Comments

It worked! Thank you very much. It solved my problem but is there any way to check if there is any validation error inside the controller ?
@black_belt No, the whole idea of using a FormRequest in this manner is the it won't get to the controller if the validation doesn't pass. The only thing you potentially could do is override the failedValidation method for this class to prevent the Exception from being thrown but that would then mean you would have to find a way to manually check if it failed and then also throw your own error.
Check my answer i did exactly that what you want to do....i send an ajax submit and if there are errors it will return them in alert and if no errors it will submit the form
Where to put this method?
@ShahrukhAnwar In the Form Request e.g. the CustomFormRequest.
2

After the update of laravel documentation, you don't need to override the response() anymore, all you have to do is just write your business logic inside the protected failedValidation() inside your custom FormRequest class like follows:

    use Illuminate\Http\Exceptions\HttpResponseException;
    use Illuminate\Contracts\Validation\Validator;

    /**
    * [failedValidation [Overriding the event validator for custom error response]]
    * @param  Validator $validator [description]
    * @return [object][object of various validation errors]
    */
    public function failedValidation(Validator $validator) { 
        // write your business logic here otherwise it will give same old JSON response
        throw new HttpResponseException(response()->json($validator->errors(), 422)); 
    }

Comments

0

I know you want the logic in your controller, but you can still leverage your Request file for this. In the Laravel documentation (assuming you are using the latest version) it is described as Adding After Hooks To Form Requests:

If you would like to add an "after" hook to a form request, you may use the withValidator method. This method receives the fully constructed validator, allowing you to call any of its methods before the validation rules are actually evaluated:

/**
 * Configure the validator instance.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}

2 Comments

I tried that but it does not allow me to throw a custom response like I wanted. But, thanks for you answer.
You're correct if you want to add data at the same level as the errors themself! If you don't mind having your own messages in the same array as the errors you could use my code. I always like to let Laravel do all the work and use as many of the features it offers as I can.
0

try this:

form.ajaxSubmit({
    async: false,
    type: yourMethod,
    url: yourRoute,
    headers: { 'X-CSRF-TOKEN': "{{csrf_token()}}" },
    dataType: 'json',
    success: function(data){
        location.href = data.redirect_to;
    },
    error: function(data) {
        var errors = data.responseJSON;
        var errorsArr = [];
        for (error in errors) {
            errorsArr.push(errors[error]);
        }

        errorsArr = $.map(errorsArr, function(n){
            return n;
        });

        alert("<strong class='text-danger'>" + errorsArr.join("<br>") + "</strong>");
        console.log(errors);

    }
});

and in your controller store method make return:

return response()->json(['redirect_to' => '/your_route']);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.