Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Deferred: Rejecting a Promise from within a Done Filter

Tags:

Fyi, I'm just starting to learn jQuery promises, so I may be a bit confused here.

Anyway, I have an AJAX request that I want to reject from within a done filter based on the content of the response:

return doAJAXRequest().then(function (data) {     if (data.responseText == "YES") {         return doOtherAJAXRequest();     } else {         this.reject(data);     } }); 

That didn't work as I expected:

Uncaught TypeError: Object #<Object> has no method 'reject' 

How do I make this promise fail based on its response? Is that possible? Or am I just confused about what needs to be done here?

like image 311
Ajedi32 Avatar asked Jul 23 '13 01:07

Ajedi32


People also ask

How use jQuery Deferred and promise?

If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. Return only the Promise object via deferred. promise() so other code can register callbacks or inspect the current state. For more information, see the documentation for Deferred object.

What does a Deferred reject mean?

When the Deferred is rejected, any failCallbacks added by deferred. then() or deferred. fail() are called. Callbacks are executed in the order they were added. Each callback is passed the args from the deferred.

What is Deferred in jQuery?

The Deferred object, introduced in jQuery 1.5, is a chainable utility object created by calling the jQuery. Deferred() method. It can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.


1 Answers

In jQuery (unlike some other libs), transmogrifying a promise from a 'resolved' state to an 'rejected' state is slightly verbose, requiring the explicit creation and rejection of a new Deferred.

function foo() {     return doAJAXRequest().then(function (data, textStatus, jqXHR) {         if (data.responseText == "YES") {             return doOtherAJAXRequest(data);         } else {             return $.Deferred().reject(jqXHR, data, 'Not YES').promise();         }     }); ) 

Here, the promise returned if data.responseText !== "YES" mimics (in part) a failed ajax request, while still allowing data to be passed. This is (probably) important for the downstream .fail() handler, which must handle both genuine ajax failures AND transmogrified success conditions, without knowing which one occurred until it reads errorThrown.

foo().fail(function(jqXHR, textStatus, errorThrown) {     if(errorThrown == 'Not YES') {         //transmogrified success         var data = textStatus;         ...     }     else {         //genuine ajax failure         ...     } });  

It is generally easier to pass data in this way rather than re-obtaining it from the jqXHR object. This is particularly true with JSON encoded data, which would otherwise need to be decoded a second time in the fail handler.

like image 168
Beetroot-Beetroot Avatar answered Oct 13 '22 10:10

Beetroot-Beetroot