Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

haakym's avatar

Showing request validation errors when submitting form by ajax

Hey everyone,

I'm writing a new project in Laravel 5 and submitting a form by ajax and I'm using a request to validate the form.

I can't quite figure out how to grab the error message data using javascript if the validation fails. As it mentions in the documentation: "If the incoming request was an ajax request, no redirect will be generated. Instead, an HTTP response with a 422 status code will be returned to the browser containing a JSON representation of the validation errors." - http://laravel.com/docs/5.0/validation#controller-validation

Any ideas how I can get access to the data returned to the browser if a validation error occurred?

0 likes
16 replies
pmall's avatar
pmall
Best Answer
Level 56

If an ajax request don't pass a form request validation, errors will be returned as json. You can catch them in the error callback of jquery ajax method :

    $.ajax({
      type: 'post',
      url: url,
      data: data,
      dataType: 'json',
      success: function(data){
        // success logic
      }),
      error: function(data){
        var errors = data.responseJSON;
        console.log(errors);
        // Render the errors with js ...
      }
    });
15 likes
usman's avatar

If you are posting a form using jQuery ajax you can use the error handler to grab the error data e.g:

...
....
error :function( jqXhr ) {
        if( jqXhr.status === 401 ) //redirect if not authenticated user.
            $( location ).prop( 'pathname', 'auth/login' );
        if( jqXhr.status === 422 ) {
        //process validation errors here.
        $errors = jqXhr.responseJSON; //this will get the errors response data.
        //show them somewhere in the markup
        //e.g
        errorsHtml = '<div class="alert alert-danger"><ul>';

        $.each( data, function( key, value ) {
            errorsHtml += '<li>' + value[0] + '</li>'; //showing only the first error.
        });
        errorsHtml += '</ul></di>';
            
        $( '#form-errors' ).html( errorsHtml ); //appending to a <div id="form-errors"></div> inside form
        } else {
            /// do some thing else
        }
    }
....

Usman.

20 likes
Ozan's avatar

@usman I am pretty sure there is a problem on that code... Where does this data come from in the $.each function?

1 like
extjac's avatar
error :function( jqXhr ) {
        if( jqXhr.status === 401 ) //redirect if not authenticated user.
            $( location ).prop( 'pathname', 'auth/login' );
        if( jqXhr.status === 422 ) {
        //process validation errors here.
        var errors = jqXhr.responseJSON; //this will get the errors response data.
        //show them somewhere in the markup
        //e.g
        errorsHtml = '<div class="alert alert-danger"><ul>';

        $.each( errors , function( key, value ) {
            errorsHtml += '<li>' + value[0] + '</li>'; //showing only the first error.
        });
        errorsHtml += '</ul></di>';
            
        $( '#form-errors' ).html( errorsHtml ); //appending to a <div id="form-errors"></div> inside form
        } else {
            /// do some thing else
        }
    }
2 likes
extjac's avatar

This is my code using toastr notifications:

var form = $("#editForm");

    $.ajax({
        url     : form.attr("action"),
        type    : form.attr("method"),
        data    : form.serialize(),
        dataType: "json",
        success : function ( json ) 
        {
            toastr.success( json.message , "Notifications" );
        },
        error   : function ( jqXhr, json, errorThrown ) 
        {
            var errors = jqXhr.responseJSON;
            var errorsHtml= '';
            $.each( errors, function( key, value ) {
                errorsHtml += '<li>' + value[0] + '</li>'; 
            });
            toastr.error( errorsHtml , "Error " + jqXhr.status +': '+ errorThrown);
        }
    })
    .done(function(response)
    {
        //
    })
    .fail(function( jqXHR, json ) 
    {
        //
    });
    return false;
2 likes
HashmatWaziri's avatar

//controller method

        $validation = \Illuminate\Support\Facades\Validator::make($request->only('start_date', 'end_date'),    $rules);

    if($validation->passes())

    {
        $update                   = Lecturer::find($id);
        $update->status           = $request->get('status');
        $update->start_date       = $request->get('start_date');
        $update->end_date         = $request->get('end_date');
        if($update->save()) {

        return response()->json([
                'success' => true,
                'message' => 'record updated'
            ], 200);

        }
    }
    $errors = $validation->errors();
    $errors =  json_decode($errors); 

    return response()->json([
        'success' => false,
        'message' => $errors
    ], 422);

// view

                   $.ajax({
                    url: URL,
                    type: 'PUT',
                    data: formdata,
                    success: function (response) {
                    window.location = "{{ URL::route('campaign.index')}}";
                      },

                    error: function(xhr,status, response) {
                        var error = jQuery.parseJSON(xhr.responseText);  // this section is key player in getting the value of the errors from controller.
                        var info = $('.edit_alert');
                        info.hide().find('ul').empty();
                            for(var k in error.message){
                                if(error.message.hasOwnProperty(k)){
                                    error.message[k].forEach(function(val){
                                        info.find('ul').append('<li>' + val + '</li>');
                                    });

                                }
                            }

                           info.slideDown();


                }

                });
eflames's avatar

I just did this and works

            error: function(data)
            {
                var errors = '';
                for(datos in data.responseJSON){
                    errors += data.responseJSON[datos] + '<br>';
                }
                $('#response').show().html(errors); //this is my div with messages
            }

So, when the request fails, the error method prints the messages from Laravel Validation system on my div .

Btw sorry for my english :D

5 likes
pjfl's avatar

Hi All..

I am not getting a 422 when the validation fails. I am getting a 302 (redirect) when I am trying to validate the form.

I am submitting to the API. can you help me to solve this?

haakym's avatar

Hi @pjfl

If your endpoint is not understanding that it's an ajax request it may be returning a redirect back with the errors instead of a failed response back with the errors as json.

You might be best creating your own question with the code you're using.

deividcriollo's avatar

error:function(data,err){ // {"message":"The given data was invalid.","errors":{"consumidorFinal":["Ingrese maximo 13 n\u00fameros"]}} var mensajes = data.responseJSON; var msg=''; $.each(mensajes.errors, function() { $.each(this, function(k, v) { msg+=v+""; }); }); msgDanger(msg); }

rehmat's avatar

In Laravel 5.6, here is what worked for me:

...........
error: function(data) {
    var errors = data.responseJSON;
    var errorsHtml = '';
    $.each(errors.errors, function( key, value ) {
      errorsHtml += '<p class="text-danger">' + value[0] + '</p>';
    });
}
...........
                
3 likes
SunnyBoy's avatar

In case anyone else is looking for help-block validation

error: function (data) {
    var errors = data.responseJSON;
    if ($.isEmptyObject(errors) == false) {
        $.each(errors.errors, function (key, value) {
            $('#' + key)
                .closest('.form-group')
                .addClass('has-error')
                .append('<span class="help-block"><strong>' + value + '</strong></span>');
        });
    }
    toastr.error( errors.message , "Error Alert", {timeOut: 3000});
}

add this before or after ajax call

$('form').find('.help-block').remove();
$('form').find('.form-group').removeClass('has-error');

Please or to participate in this conversation.