Skip to content

Instantly share code, notes, and snippets.

@tobiashm
Last active October 23, 2018 12:03
Show Gist options
  • Save tobiashm/0a987db2f9ec8e5cdbb3 to your computer and use it in GitHub Desktop.
Save tobiashm/0a987db2f9ec8e5cdbb3 to your computer and use it in GitHub Desktop.
Wrap jQuery AJAX in ES6 Promise
function AjaxError(jqXHR, textStatus, errorThrown) {
this.name = "AjaxError";
this.message = textStatus;
this.jqXHR = jqXHR;
this.errorThrown = errorThrown;
}
AjaxError.prototype = new Error();
AjaxError.prototype.constructor = AjaxError;
(function($) {
function decorateAsJQuery(promise) {
promise.done = function(fn) {
return decorateAsJQuery(promise.then(fn));
};
promise.fail = function(fn) {
return decorateAsJQuery(promise.then(null, fn));
};
promise.complete = function(fn) {
return decorateAsJQuery(promise.then(fn, fn));
};
return promise;
}
var jqAjax = $.ajax;
$.ajax = function ajax() {
var args = Array.prototype.slice.call(arguments);
var jqPromise = jqAjax.apply(this, args);
var promise = new Promise(function(resolve, reject) {
jqPromise.then(function(data, textStatus, jqXHR) {
resolve(data);
}, function(jqXHR, textStatus, errorThrown) {
reject(new AjaxError(jqXHR, textStatus, errorThrown));
});
});
return decorateAsJQuery(promise);
};
})(jQuery);
@justin808
Copy link

What are the advantages of doing this over using the simple http://api.jquery.com/category/deferred-object/?

@kyouko-taiga
Copy link

To the best of my knowledge, jQuery's deferred object aren't Promise/A+ compliant. In particular, they don't catch errors in reactions.
You can find numerous blog posts on the subject that will explain the the subtle differences. For instance, I suggest you have a look at JavaScript Promises, by Jake Archibald

@hxgdzyuyi
Copy link

jqXHR is a superset of the browser's native XMLHttpRequest object.

Such as: abort current request

var jqXHR = $.ajax(...)
jqXHR.abort()

@Perseid
Copy link

Perseid commented Mar 3, 2016

Is this free software and if yes, would you mind explicitly putting a license on top? I would very much like to reuse it in a project.

@malthejorgensen
Copy link

This breaks the jQuery AJAX load-function ($(element).load(someURL)), since jQuery 2.2.0 and 3.0.0 (see jquery/jquery@97ef1f2), as the .always() function is used instead of the deprecated .complete().

This can be fixed by adding the line promise.always = promise.complete; between lines 20 and 21.

@malthejorgensen
Copy link

Also, the reason why you would use this is to be able to use .catch() on a chain of promises, so that you can have a single error handler if any one call in a series of AJAX calls fail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment