Intro to Error Handling in Ajax Apps

Elijah Manor | May 15, 2010

 

Let’s face it. You’re most likely already doing some sort of Ajax in your current web application, and if you aren’t using Ajax, your clients probably want you to starting using it very soon. This article aims to explore the Ajax support in the jQuery JavaScript library. It focuses first on some simple, common approaches to get you started using Ajax. Next, it describes handling errors with these simple methods, and then it proceeds to explore the low-level Ajax interface that jQuery provides to give you power and flexibility. Along the way I utilize and recommend jQuery plugins that can help you master some of these techniques.

Ajax Shorthand Methods

Before we get into the actual techniques of error handling in Ajax applications, let’s focus on the five shorthand methods that jQuery provides to let you quickly and easily get the data you want.

$.get

The $.get method allows you to load the contents of a resource within your domain (unless you are using JSONP) by using a HTTP GET request. It also allows you to easily manipulate the data in a callback method.

The following example binds a click handler to a button. When the button is clicked, a HTTP Get request is initiated, pulling out the specified pet. Once the response is successfully received, the data is outputted to the div element with the id attribute of pet. Figure 1 shows the result after a HTTP Get request. The data argument contains the response value.


Figure 1: Viewing the data returned from a HTTP Get request

$.getJSON

The $.getJSON method also initiates a HTTP GET request to a resource—like the $.get method—but behind the scenes the response is parsed using JSON, and the resultant object is passed to the callback function.

The following is a simple example using $.getJSON with the Twitter API. The code actually uses JSONP, which allows the request to go across domains, but that isn’t the point of this example. The main point is that the data returned to the callback method is an object that is parsed from the Twitter response.

You can view, run, and edit the preceding source code from my jsFiddle account. Figure 2 shows code to retrieve tweets from Twitter using the $.getJSON method.


Figure 2: Using the $.getJSON method to retrieve tweets from Twitter

$.getScript

This method retrieves a JavaScript file using the HTTP Get request and then immediately executes the script in the global context. By the time the callback method is called, the script has already been executed.

In the following example, I utilize the Modernizr Feature Detection Library written by Faruk Ateş and Paul Irish to determine whether the current browser supports the border-radius CSS3 feature. If the feature doesn’t exist, the code loads the jQuery Corner Plugin written by Mike Alsup to apply corners around the main div.

.load

The .load method also uses a HTTP Get request to retrieve data from the server, but this one doesn’t have a callback function. You start with a jQuery object to which you want the output of the Ajax call to be written. Then you call the .load method off the jQuery object, passing the URL of the resource to retrieve. In addition, you can provide a selector after the URL to indicate which portion of the response you want written to the jQuery object.

For example, the following code includes a Get Pets button and an empty div. When the button is clicked, the .load method is called off the output div, passing the URL to “/Pet/Index table”. This gets the response from the Ajax request, and then selects the table from the output and writes it in the div. The page is shown in Figure 3.


Figure 3: Using the .load method to retrieve data from a URL but only show the table selection

$.post

The $.post method uses the HTTP Post request to load data from a server. This method is usually used in combination with an HTML Form element to submit a request without causing a page refresh.

The following code example attaches to the Submit button and serializes the HTML Form input values, passing them to the $.post method along with a URL. When the post is successfully completed, the method calls back to the function you provide. In this case, we are just outputting the status of the request, but you also have access to the data returned and the XMLHttpRequest (which I’ve represented as xhr).

First, here’s the HTML markup that serves as the HTML Form for this and many of the remaining examples in this article.

Figure 4 shows the page that’s generated.


Figure 4: The serialized form data and the result of the $.post

A little later in this article, I describe an easier way to do form posts using a jQuery plug-in, but for now let’s see how you can track any errors by using the shorthand methods just described.

Error Handling using AJAX Shorthand Methods

In reading the sections that detail how to use the shorthand Ajax methods that jQuery provides, you might have noticed that I didn’t handle any negative error scenarios. jQuery provides a set of six Ajax events that you can subscribe to in order to keep track of Ajax requests and responses.

You can take the earlier $.post example and modify it to subscribe to all the following Ajax events to add blocking and notification messages.

  1. .ajaxStart()
  2. .ajaxSend( handler( event, XMLHttpRequest, ajaxOptions ) )
  3. .ajaxSuccess( handler( event, XMLHttpRequest, ajaxOptions ) )
  4. .ajaxError( handler( event, XMLHttpRequest, ajaxOptions, thrownError ) )
  5. .ajaxComplete( handler( event, XMLHttpRequest, ajaxOptions ) )
  6. .ajaxStop()

These events fire in the order shown. Depending on the outcome of the request, either ajaxSuccess or ajaxError fires along the way.

In the following code sample, I have updated the $.post success callback to use the Pines Notify jQuery Plugin written by Hunter Perrin to give feedback to the user about the status of the Ajax request.

Now, let’s wire up some Ajax events to capture the full life cycle of the Ajax request and response.

Here I am using the jQuery BlockUI Plugin written by Mike Alsup to block user input during the Ajax life cycle. You can see where I am blocking the UI in ajaxStart and then unblocking it in ajaxStop. The code appends the URL at the point where it is about to post in ajaxSend, and depending on whether the response is successful or not, ajaxComplete or ajaxError is executed.

The Ajax events listed earlier are fired for any Ajax type method that jQuery provides. So, if you want one of these events to be specific to a particular Ajax call, you need to add additional logic to match the URL or some other unique identifier to do something special. If you want specific behavior for one of these events, you might also be interested in the $.ajax method, which I discuss in the next section. It provides much more granular control over the whole Ajax life cycle.

jQuery AJAX Method

There is one more method that we need to cover, and that is the $.ajax method. As it turns out, all of the Ajax shorthand methods ($.get, $.getJSON, $.post, and so on) can be achieved with the jQuery $.ajax method. They are essentially wrappers around the $.ajax method.

For example, the $.get method shown near the beginning of this article could be rewritten as follows:

And similarly, the $.post method could be rewritten this way:

But instead of focusing on how you can rewrite the Ajax shorthand methods, let’s focus on the things you can’t do with them. The $.ajax method has a long list of options that it provides.

To give you an idea of some of the things you have control over using the $.ajax method, here is a small subset of the options (you can find a full list from the jQuery.ajax() API):

  • async
  • beforeSend(XMLHttpRequest)
  • cache
  • complete(XMLHttpRequest, textStatus)
  • contentType
  • context
  • data
  • dataFilter(data, type)
  • dataType
  • error(XMLHttpRequest, textStatus, errorThrown)
  • password
  • success(data, textStatus, XMLHttpRequest)
  • timeout
  • url
  • username
  • xhr

Let’s use some of these $.ajax options and focus on rewriting the Edit Pet post example using blocking, notifications, and error handling. Here’s the code:

Query Form Plugin

Another alternative to the preceding post scenario is to use the jQuery Form Plugin written by Mike Alsup.

Let’s say that we have a form and want the output of the response to be written to a particular DOM element. Well, that is very easy with the jQuery Form Plugin.

That’s it. You first select the form you want to use, and the plugin grabs the URL and the method type (GET or POST), serializes the form data for you, processes the success, and writes the output to the target you specified in the options. In addition, there are many more features that this plugin provides that the standard $.ajax method does not. For example, you could add a clearForm: true option to the preceding code example that would empty the input elements after the response is successful. Operations like this are very easy. You can find a list of these features from the plugin’s options page.

You are not sacrificing the granularity you have when you use the $.ajax method directly. The plugin provides all the same hooks into the Ajax life cycle that you can register and tweak. For example, I rewrote the example we used in the jQuery $.ajax method by using the jQuery Form plugin shown here:

Other Considerations

I don’t plan to expand on the following topics in detail, but I did want to bring up a few items that you should consider when you write and debug Ajax applications.

Back Button and History Support

Adding Ajax support to your website is great for user interaction, but there are consequences that you soon run across (if you haven’t already) that might require some attention on your part.

Since Ajax-rich pages are heavily controlled by dynamic content, they tend to change a lot in the way they look. For example, you might be changing tabs that dynamically load content via Ajax calls. The problem comes when you want to bookmark a specific tab that has specific content. The browser doesn’t keep a history of what you’ve done with JavaScript and Ajax, so it becomes very difficult to accurately bookmark a specific state of your web page.

Also, after interacting heavily with an Ajax-rich web page, the Back button doesn’t necessarily do what the user intended. The Back button returns to the previous non-Ajax request, which may have been several actions ago depending on your application.

Fortunately, several libraries are available that provide the tools you need to properly support the Back button and provide bookmarkable content. One of the better jQuery libraries to handle this is the jQuery BBQ Plugin written by Ben Alman.

Form Serialization Concerns

As of jQuery 1.4, the code for the $.param method has changed somewhat, which could affect your code depending on what server-side framework you are using. The new functionality works best with PHP and Ruby on Rails, but you might have some issues with other frameworks, such as ASP.NET or ASP.NET MVC.

For more information about the change and its implications, you can reference a detailed article by Ben Alman entitled jQuery 1.4 Param Demystified.

If you find yourself having issues with the way jQuery 1.4 serializes your data, you can change the behavior to mimic jQuery 1.3.2 by passing in the traditional Boolean option to the $.ajax call or by globally adding the following line to your project.

Conclusion

jQuery provides numerous methods to get you started adding Ajax to your applications. You have basic shorthand methods and also a fine-grained $.ajax method that has a load of features. There are also numerous top-notch jQuery plugins in the community to help make implementing Ajax easier, more attractive, and more user friendly.

The jQuery Plugins that I mentioned and recommend in this article are the following:

You can download the code associated with this article from my jQueryAjaxErrorHandling GitHub repository.

If you are interested in continuing your jQuery learning, you can follow me on Twitter for a fresh set of jQuery links. Also check out my blog for my daily Tech Tweets roundup of blog posts that contains numerous jQuery links to aid in your learning process.

 

About the Author

Elijah Manor is a Christian and a family man. He develops at appendTo as a Senior Architect providing corporate jQuery support, training, and consulting. He is an ASP.NET  MVP, ASPInsider, and specializes in ASP.NET MVC and jQuery development. He enjoys blogging about the things he learns. He is also active on Twitter and provides daily up-to-date Tech Tweets.

Find Elijah on: