This code snippet worked in 1.7.2 with both success/error callbacks as well as promises style callbacks. With 1.8.2 the success/error callbacks still work but the promises do not. My hunch is that the return dfd.promise(jqXHR);
line is the problem but im not certain.
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
// Don't infinitely recurse
originalOptions._retry = isNaN(originalOptions._retry)
? Common.auth.maxExpiredAuthorizationRetries
: originalOptions._retry - 1;
// set up to date authorization header with every request
jqXHR.setRequestHeader("Authorization", Common.auth.getAuthorizationHeader());
// save the original error callback for later
if (originalOptions.error)
originalOptions._error = originalOptions.error;
// overwrite *current request* error callback
options.error = $.noop();
// setup our own deferred object to also support promises that are only invoked
// once all of the retry attempts have been exhausted
var dfd = $.Deferred();
jqXHR.done(dfd.resolve);
// if the request fails, do something else yet still resolve
jqXHR.fail(function () {
var args = Array.prototype.slice.call(arguments);
if (jqXHR.status === 401 && originalOptions._retry > 0) {
// refresh the oauth credentials for the next attempt(s)
// (will be stored and returned by Common.auth.getAuthorizationHeader())
Common.auth.handleUnauthorized();
// retry with our modified
$.ajax(originalOptions).then(dfd.resolve, dfd.reject);
} else {
// add our _error callback to our promise object
if (originalOptions._error)
dfd.fail(originalOptions._error);
dfd.rejectWith(jqXHR, args);
}
});
// NOW override the jqXHR's promise functions with our deferred
return dfd.promise(jqXHR);
});
Update: Here is my ajax request that fails:
$.ajax({
url: someFunctionToGetUrl(),
// works
//success: callback,
//error: ajaxErrorHandler
}).then(
[callback],
[errorback, ajaxErrorHandler]
);
};
Edit: This is a documentation bug, but the behavior is by design. The api changed such that deferred.then
now behaves like deferred.pipe
and no longer allows arrays to be passed in, but the documentation hasn't been updated to reflect that.
Related bugs:
The workaround I describe at the end of my original answer below still applies.
Original answer:
It looks like a jQuery bug to me. If you pass in a single function reference as the first argument, it works, but not if you pass in an array of functions:
http://jsfiddle.net/tunDH/
But, the documentation says an array of functions is just fine:
doneCallbacks A function, or array of functions, called when the Deferred is resolved.
And, you are right. It does work with jQuery 1.7: http://jsfiddle.net/tunDH/1/
A workaround would be to wrap all your function calls inside a single function, instead of inside an array:
$.ajax({
url: someFunctionToGetUrl(),
// works
//success: callback,
//error: ajaxErrorHandler
}).then(
function(){
callback1.apply(this, arguments);
callback2.apply(this, arguments);
},
[errorback, ajaxErrorHandler]
);
http://jsfiddle.net/tunDH/2/
You'll probably need to do the same thing with the error callbacks, but I didn't test that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With