0

How can I force a successful response from $.ajax to fire its "fail" handlers from within a "done" handler?

The jQuery documentation says the jqXHR object implements the Promise interface, which means it has no reject method.

Below shows some code listening for failures on a jqXHR object created inside another scope.

If the successful response is actually a well-formed error, I want to trigger handlers that are listening for "fail".

// common function
function doAjax(options) {
  return $.ajax(options).fail(function() {
    // common error handling
  }.done(function(result, status, xhr) {
    if (result.isBAD) {
      xhr.reject(); // <- not a jqXHR method
    }
  }));
}

// listening elsewhere
doAjax(options).fail(function() {
  // specific error handling
});
Tim
  • 8,036
  • 2
  • 36
  • 52
  • I don't believe you can. Given that `done`/`fail` is intended to work on the state of the request, not its content, the logic you're trying to create goes against that principle. – Rory McCrossan May 15 '20 at 14:00
  • 1
    Perhaps the doAjax function could return a custom Deferred object instead? – Tim May 15 '20 at 14:02
  • I guess that would mean client code not having access to the original XMLHttpRequest, but I might be able to live with that – Tim May 15 '20 at 14:05
  • Yes, you could return your own promise/deferred that you choose the cases that get resolved/rejected. – Taplar May 15 '20 at 14:47
  • Possible same question: https://stackoverflow.com/questions/17800176/jquery-deferred-rejecting-a-promise-from-within-a-done-filter – freedomn-m May 15 '20 at 14:59
  • thanks @freedomn-m I did look for existing Qs, but failed to find that one. – Tim May 15 '20 at 15:53

1 Answers1

0

I fixed this by returning my own promise instead of the jqXHR instance. It means that client code doesn't have access to other ajax details, but in my case this isn't a problem.

function doAjax(options) {
  var deferred = $.Deferred();
  return $.ajax(options)
    .fail( function() {
      deferred.reject();
    })
    .done( function(result,status,xhr) {
      if( result.isBAD ){
        deferred.reject();
      }else {
        deferred.resolve();
      }
    })
  ;
  return deferred.promise();
}
Tim
  • 8,036
  • 2
  • 36
  • 52