1024px-Flatirons_Winter_Sunrise_edit_2

jQuery Ajax features provide a slick way to make asynchronous javascript calls from any browser. jQuery even gives us helpers methods to make the calls even simpler. $.get, $.getJSON, $.getScript, $.load, and $.post all give great ways to set up default features and get your ajax calls done quickly. We often see enterprise developers taking advantage of these shortcut methods for basic Ajax needs.

However, enterprises today require scalable solutions that gracefully handle errors, messages to the user, spinners, and other aspects of a rich user experience. In these series of posts we are going to step beyond the basic Ajax functionality and build a scalable library solution. In order to create a functional library you’ll need to understand the .ajax method and the parameters allowed. If you don’t already have a handle on .ajax, please visit the extremely useful api site for a quick primer.

For the purpose of these posts we are going to start with a pattern that is often seen in enterprise situations for ajax calls. In the below example we will attempt to retrieve data from the server with a GET http action via the jQuery.ajax method. The example will show an animated gif to identify loading (hereafter referred to as a spinner). We will retrieve HTML from the server, and apply that HTML to the DOM using jQuery’s .html() function. Finally we will hide our spinner on success or failure of the call by using the complete callback.

[js] $(‘#mySpinnerId’).show(); //show my spinner
$.ajax({
url: ‘myUrl’,
dataType: ‘html’,
cache: false,
success: function(myHtml) {
$(‘#myHtmlContainer’).html(myHtml);
},
complete: function() {
$(‘#mySpinnerId’).hide(); //hide the spinner
}
});
[/js]

This functions great for our site, and we decide to move on to another Ajax request. Our second request:

[js] $(‘#mySpinnerId2’).show(); //show my spinner
$.ajax({
url: ‘myOtherUrl’,
cache: false,
dataType: ‘json’,
success: function(myJson) {
// assumes a JSON structure that at least
// includes {"value":"someValue"}
$(‘#someId’).text(myJson.value);
},
complete: function() {
// hide the spinner
$(‘#mySpinnerId2’).hide();
}
});
[/js]

Wonderful. This works as well. But it is not elegant code. How do we keep from repeating ourselves? Is there a better way to set up the loading animations? How do we handle errors?

Taking a Step Back

Before DRYing out this code, lets review the series of callbacks and functionality available to us with jQuery Ajax.

Ajax Settings (In API)

.ajaxSetup allow us to set up defaults for any of the parameters available in $.ajax. In our case, it would make sense to set up caching settings to be default

Ajax Event Broadcasting

A somewhat obscure documentation page lists out some incredibly important information. A quick summary:

Local vs Global Events

There are some events that are broadcasted for the specific ajax call, and other that are broadcast for any ajax call. Global event names always have the “ajax” prefix on the name. Local events do not.

Order of event broadcasting

There is a rich set of events that we can tap into for any of our ajax needs. In particular, we have events that will fire on any error, as well as firing on the completion of code.

Given that information, lets create an object that will handle a few things: 1) showing/hiding spinners 2) setting up defaults that are specific to our website.

[js] var mySiteAjax = (function($){
return {
getViaAjax: function(params){
var settings = $.extend({
url: ”,
spinner: undefined,
dataType: ‘html’,
cache: false,
success: function(){}
}, params);

};
})(jQuery);
[/js]

Your response might be “I thought you were creating an object? What is all of this?” Lets cover it in pieces:

Self executing (invoking) anonymous functions

[js] function($){

})(jQuery);
[/js]

This pattern is a well known one in javascript. This pattern allows us to create a function without a name (anonymously so that we don’t pollute the global scope), and then immediately execute it. Specifically we are using the pattern so that we can accept jQuery as a parameter to a function, but use the variable ‘$’ internally in the function. This allows us to ensure that if any third party library were attached and this code was in a library attached afterwards, it would still behave as expected.

jQuery.extend()

$.extend is another piece of jQuery beauty that allows us to set up default parameters very easily.

return object literal

Note that we are creating an function and then immediately executing that function. Thus whatever is returned by the function will be assigned to mySiteAjax. In this case, it is an object literal which includes a single function – getViaAjax.

Usage

Given our two example above, here is the usage:

Example 1:

[js] mySiteAjax.getViaAjax({
spinner : ‘#mySpinnerId’,
url : ‘myUrl’,
success : function(myHtml){
$(‘#myHtmlContainer’).html(myHtml);
}
});
[/js]

Example 2:

[js] mySiteAjax.getViaAjax({
spinner : ‘#mySpinnerId’,
url : ‘myUrl’,
dataType: ‘json’,
success : function(myJson){
$(‘#someId’).text(myJson.value);
}
});
[/js]

We’ve saved ourselves some code. But more importantly, we’ve started down the path of creating a library that can handle all of our site’s ajax needs in an elegant manner.

Over this series, we will continue to expand our mySiteAjax object to include more behavior. Next up, we’ll cover a error handling strategy.

  • Part 2: Handling errors and global loading animations
  • Part 3: JSON wrapper
  • Part 4: Putting it all together