Background on $.ajax logging using Ajax Global Events: So I’ve moved from jQuery 1.4 to 1.9. I have some time to refactor my code to take advantage of some of the new features of 1.9 and to get ready for 1.10; the next jQuery release removes some of the deprecated methods.
For this round of coding, I am focusing on the $.ajax()
method. In my present design, my single page web application makes REST calls for many of the UI menu items. For example, a click on the FILE->LOAD menu item triggers a function call to code that retrieves a file from my server. The basic pattern is like this:
// Start spinner // start logging timer $.ajax({"url":RestURI, "type":"GET", "dataType":"json", success: function(data) { // Do success stuff (parse, format and display) // stop logging timer, do logging // stop spinnger }, /* end success: */ error: function (req, stat, err) { // Do error stuff // stop logging timer, do logging // stop spinner } /* end error: */ });
I have more than 7 code blocks that follow this pattern. Since the success/error/complete callback functions have been deprecated and I need to touch the code anyways, I thought I’d use the newish $.ajax()
global events handlers to clean up my code. The event handlers seem to be a useful place to put common pieces of code that really shouldn’t have been so liberally cut-and-pasted when I wrote the original code.
For each of my ajax code blocks, I put a generous amount of logging in. Maybe this logging should only be needed when writing/debugging the code, but for me, since I spend so little dedicated time on this application, I wanted to keep verbose logging on always to make it real easy for me to debug.
$.ajax logging using Ajax Global Events
The following new block of code is doing my $.ajax
logging using Ajax Global Events.
$(document).ajaxSend(function(evt, xhr, settings) { console.log(settings.type+" "+settings.url+" Sent"); start = new Date().getTime(); // Other logging }); $(document).ajaxSuccess(function(evt, xhr, settings) { console.log(settings.type+" "+settings.url+" Success"); // Other logging }); $(document).ajaxError(function(evt, xhr, settings, exc) { console.log( settings.type+" "+settings.url+" Failed. " +xhr.status+"-"+xhr.statusText); // Other logging }); $(document).ajaxComplete(function(evt, xhr, settings) { console.log(settings.type+" "+settings.url+" Complete"); end = new Date().getTime(); diff = end - start; // Other logging });
As you can see, the ajaxSend/ajaxSuccess/ajaxError/ajaxComplete events are fired in sequence at the $.ajax()
function executes and after the .done()
, .fail()
and .compete()
callbacks are executed.
The “Other logging” comment represents 2 or 3 lines of code where I put logging information into a user visible menu item (REPORTS->LOG) where I can see even more details without having to open the console window. For me, this effort is a nice clean out some of the logging stuff, to make the application logic a little more visible; this clears up a bunch of clutter for me.
New-ish .done/.fail/.always Callbacks
Therefore, my $.ajax() code blocks are straighten out to follow the new done/fail/always callbacks. Here’s an example new $.ajax() code block:
// Start spinner $.ajax({url:RestURI, type:"GET", dataType:"json"}) .done( function(data, textStatus, jqXHR) { // Do success stuff }) /* end done: */ .fail( function (jqXHR, textStatus, err) { // Do error stuff }) /* end fail */ .always( function() { // stop spinner }); /* End always */
Some things to note: I still put the start/stop spinner function calls inline. I may move this to the global even handlers, but not yet.
Deferred Objects
Also, the done/fail/always call backs follow the new Deferred Object model. This will then let me setup some promise objects to let me address some of the async race conditions I have in my application.
For example, I have a case where I can run FILE->SAVE and then run REPORT->General and the report will produce results before the save was completed. I know how to fix this, but I was looking to use my new ajax code blocks architecture to get some practice with promise objects instead… for next time.