Provide default fail method for jQuery deferred object

I am writing a Javascript API client using jQuery. My top level query method is as follows:

function request(method, uri, params, proxies) { var deferred = $.Deferred(); $.ajax({ data: method == 'GET' ? params : JSON.stringify(params), contentType: 'application/json', dataType: 'json', url: api.root + uri, type: method, xhrFields: { withCredentials: true } }).done(function(body) { deferred.resolveWith(this, [body.data]); }).fail(function(xhr) { deferred.rejectWith(this, [xhr]); }); return deferred.promise(); }, 

How can I use the default fail handler for my returned delay? That is, if the deferred has no other handlers associated with it fail , call the default handler.

I want to do this in order to have global exception handling in my application, with the exception of those parts that have specific handling (and will define their own fail handler on deferred).

+6
source share
1 answer

So, the cleanest way to use jQuery ajax in the API as of 2016 is to return a promise. But you cannot determine if the caller has connected an error handler or not.

So, I would suggest that you simply add a new argument to your function, which tells the function NOT to use the default error handling, because the caller will take care of the error handling. And I would advise you to avoid the anti-template promise by simply using the existing $.ajax() promise already returning, and not creating its own deferred:

 function request(method, uri, params, proxies, skipDefaultErrorHandling){ // default error handling will be used if nothing is passed // for skipDefaultErrorHandling var p = $.ajax({ data: method=='GET'?params:JSON.stringify(params), contentType: 'application/json', dataType: 'json', url: api.root + uri, type: method, xhrFields: { withCredentials: true } }); if (!skipDefaultErrorHandling) { // apply default error handling p = p.then(null, function(jqXHR, textStatus, errorThrown) { // put here whatever you want the default error handling to be // then return the rejection with the various error parameters available return $.Deferred().reject([jqXHR, textStatus, errorThrown]); }); } return p; }; 

Then the caller simply decides whether to apply their own error handling or not:

 request(...).then(function(data) { // success code here }); 

Or you can go with a callback without promising a failHandler that you will pass, and your default error handling looks like to see if that failHandler passed or not. This is a hybrid of promises and callbacks and is not what I usually choose for the architect, but since your question asks for something that promises does not support, this is one of the achievements:

 function request(method, uri, params, proxies, failHandler){ // default error handling will be used if nothing is passed // for skipDefaultErrorHandling var p = $.ajax({ data: method=='GET'?params:JSON.stringify(params), contentType: 'application/json', dataType: 'json', url: api.root + uri, type: method, xhrFields: { withCredentials: true } }); // apply default error handling p = p.then(null, function(jqXHR, textStatus, errorThrown) { if (failHandler) { // call passed in error handling failHandler.apply(this, arguments); } else { // do your default error handling here } // then keep the promise rejected so the caller doesn't think it // succeeded when it actually failed return $.Deferred().reject([jqXHR, textStatus, errorThrown]); }); return p; }; 
+3
source

Source: https://habr.com/ru/post/954967/


All Articles