jQuery’s abort() method on AJAX requests still calls the fail() callback function

I am working on a piece of cloud software that allows users to generate Text Codes (those nifty letters and numbers you can send to a short phone number to sign up for events, coupons, etc.).  One of the requested features was an inline validation checker for the actual text code (since the codes would all be for the same phone number, each has to be unique).

No problem.  Let’s create the input and bind some fancy listeners on key events!

<input id="textcode" type="text" class="form-control col-md-7 col-xs-12 @if($errors->has('textcode')) parsley-error @endif"
name="textcode" value="{{ old('textcode') }}" required>

Javascript:

function watchTextCodeInput()
{
    var $input = $('input[name=textcode]');
    var $currentRequest = false;
    //on keydown, clear the countdown
    $input.on('keyup', function () {

        this.value = this.value.toLocaleUpperCase();
        var textcode = $input.val();

        $input.removeClass('parsley-validated');
        $input.removeClass('parsley-success');
        $input.removeClass('parsley-error');

        $input.parent().parent().find('.parsley-errors-list').remove();

        // if $currentRequest is now defined as an ajax object, abort it
        if($currentRequest !== false){
            $currentRequest.abort();
            $currentRequest = false;
        }

        if(textcode.length > 3){

            $currentRequest = $.getJSON('/admin/textcodes/check_code/' +     textcode, function(res){

                $input.addClass('parsley-validated parsley-success');

           }).fail(function(res){

                res = res.responseJSON;
                var message = res.valid ? 'Text Code Unavailable' : 'Text Code is invalid format.';
                // Perform other business here...

           });
       }
    });
}

Everything looks fine on the surface, but when testing the code, I ran into an immediate issue – for some reason,  I was getting an error in the console for attempting to find the property ‘valid’ of ‘undefined’.

A little digging through the stack, and I discover that it is being thrown in the .fail() callback – even though I had aborted the call!

Turns out, after some research, that jQuery still calls the .fail() callback on all $.ajax requests ($.getJSON, $.post, $.get, etc.).  This post describes the same issue, and is what helped me track down the issue.

I agree with the sentiment that a call to .abort() should not be considered a failure, but rather a halt.  A failure should only apply if the request was allowed to continue and actually failed due to server, network, or other errors.

The solution appear to be to check the test status passed as the second argument to the .fail() callback function.

function watchTextCodeInput()
{
    var $input = $('input[name=textcode]');
    var $currentRequest = false;
    //on keydown, clear the countdown
    $input.on('keyup', function () {

        this.value = this.value.toLocaleUpperCase();
        var textcode = $input.val();

        $input.removeClass('parsley-validated');
        $input.removeClass('parsley-success');
        $input.removeClass('parsley-error');

        $input.parent().parent().find('.parsley-errors-list').remove();

        // if $currentRequest is now defined as an ajax object, abort it
        if($currentRequest !== false){
            $currentRequest.abort();
            $currentRequest = false;
        }

        if(textcode.length > 3){

            $currentRequest = $.getJSON('/admin/textcodes/check_code/' +     textcode, function(res){

                $input.addClass('parsley-validated parsley-success');

           }).fail(function(res, textStatus){
               if(textStatus !== 'abort'){
                    res = res.responseJSON;
                    var message = res.valid ? 'Text Code Unavailable' : 'Text Code is invalid format.';
                    // Perform other business here...
               }
           });
       }
    });
}

After that, the request performed as expected.