Introduction to the Dojo toolkit, Part 2: Infrastructure code

Get Dojo's support for standard Ajax requirements

Sunil Patil concludes his introduction to the Dojo toolkit by walking you through an email client application that demonstrates Dojo's support for common Ajax requirements. See for yourself how Dojo's unified API takes the hard work out of implementing cross-browser compatibility, error handling, and data encoding in your Ajax applications. Level: Intermediate

The first half of this article got you up to speed with the basics of working with the Dojo toolkit. You learned how to install Dojo in your Web applications, and you developed a simple Hello World program. In the process you learned first-hand how the toolkit's infrastructure for classes and modules simplifies the writing of object-oriented, well-scoped JavaScript. In this second half of the article we'll enter more advanced territory, with a look at the real-world requirements of Ajax applications. You'll then learn about the infrastructure code Dojo provides to help you handle these requirements, even in complex application scenarios.

Ajax is a foundational technology for Web 2.0 applications. Ajax applications typically have three requirements:

  1. A (usually asynchronous) request to the server that gets a response without requiring the browser page to be refreshed
  2. A modification to the page document -- such as a color change or the addition or removal of some content -- that indicates visually to the user that the response has occurred
  3. Eventing, which allows you to attach a JavaScript function to a user- or system-initiated event -- a button click by the user, for example -- so that the function is called when the event occurs

Dojo simplifies the development of all three of these Ajax requirements and ensures that the resulting application will work in multiple browsers. It does this by providing an infrastructure for making asynchronous requests, and for using cross-browser-compatible DOM-manipulation code. In the next sections I'll introduce you to the key elements of Dojo's Ajax infrastructure and show you how to use it in Ajax development.

Making an XMLHttpRequest

Most browsers provide a XMLHttpRequest object that allows you to make an asynchronous request to the server and get a response without refreshing the whole page. But if you try to use the XMLHttpRequest object directly without using a JavaScript framework such as Dojo, you'll run into problems such as memory leaks and divergent, browser-specific APIs. The Dojo toolkit simplifies the use of XMLHttpRequest by providing a set of wrapper functions for the object. The wrapper functions address common infrastructural issues by providing a unified API, cross-browser compatibility, error handling, data encoding, and much more.

The four wrapper functions all start with xhr (a short form of XMLHttpRequest):

  • xhrGet() allows you to make an HTTP GET method call to the server.
  • xhrPost() allows you to make an HTTP POST method call to the server.
  • xhrPut() allows you to make an HTTP PUT method call to the server.
  • xhrDelete() allows you to make an HTTP DELETE method call to the server.

Dojo also provides a generic xhr() function that takes the name of the HTTP method that you want to use as an argument and makes the requested method call.

Dojo defines properties that you can pass to the XHR methods. Most have a default value. To override the defaults, you can assign the values you want to a set of properties and pass that set as an argument to the DHR method you're using. The properties Dojo defines are:

  • url: This is a required property that has no default value. It indicates the URL that you want to make the request to and get a response from. It must be same host and port that serves the page, a restriction based on a browsers' same origin policy.
  • handleAs: This optional property indicates how you want Dojo to handle the server response. The available options are:
    • text (the default): Return the response data as a string. It's your responsibility to decode and use that data.
    • xml: Returns the response data as a document object. If the client's browser is other than Internet Explorer (IE), Dojo returns xhr.responseXML. If the client browser is IE, then it creates an XMLDOM object, loads the server response in that object, and returns it.
    • json: Parse the response string, which is in the JavaScript Object Notation (JSON) format into a JavaScript object using the dojo.fromJson() call; throw an error if the response string is invalid JSON.
    • javascript: Evaluate the response string as JavaScript in global scope using the dojo.eval() call.
    • json-comment-optional: Check if the response string has JavaScript comments in it. If it does, throw an error; if not, parse that string as a JSON object using the dojo.fromJson() call. (This option was meant to deprecate warnings about the poor security of client-side JSON parsing and XML.)
  • timeout: This optional property defines the time in milliseconds to wait before giving up the XHR call and throwing an error. The default value is 1000.
  • sync: This is an optional property, with a default value of false, that determines if the XHR call to the server should be synchronous or asynchronous. A value of true causes Dojo to make a synchronous request to the sever.
  • form: This optional property defines what form should be submitted with the request. Its value can be either a DOM node representing the form, or a string representing the value of the form's id attribute. Dojo calls the dojo.formToObject() method with the supplied form id, and the dojo.formToObject() returns the values encoded in an HTML form as string properties in an object. Disabled form elements, buttons, and other non-value form elements are skipped. Multi-select elements are returned as an array of string values.
  • content: If this optional property is set, it should contain a set of properties with string values. Dojo passes those properties in a request along with the data collected from the form.

In addition, you can set the following three properties. Each one's value acts as callback function that's invoked once the response is returned from the server:

  • load: This callback function is called if the Ajax request completes successfully. Dojo passes it the data returned by the response, along with the XHR properties that you passed to the dojo.xhr at the time of invoking it.
  • error: This callback function is called if an error occurs in the Ajax request -- either because the Ajax call timed out or there was some error on the server side or the URL was invalid. The basic idea is that if the HTTP response code is unsuccessful, the error function is called. The first parameter passed to the error function is a JavaScript Error object indicating what the failure was; the second argument is the set of XHR properties that you passed to dojo.xhr() at the time of invoking it..
  • handle: If you don't want two different functions to handle both successful and unsuccessful Ajax requests, then you can set a callback function that's invoked under both conditions. It gets response data and an XHR properties object as arguments in the case of a successful Ajax request, and error and an XHR properties object as arguments if an error occurs. Choose this option with care, because you might end up writing your own infrastructure code to figure out if the request succeeds or fails and to handle it accordingly.

The sample application

Now that you know how the XHR methods operate, we'll develop a sample email client application with Ajax features. The first page request will load a template page, with header, footer, side menu, and body. Thereafter every user interaction will change only the body of the page without refreshing the page. You'll build the client side of the sample application using the Dojo toolkit. The server side is a Java EE application that uses Apache Struts 1.0. To keep things simple, we'll use a static list of email messages in the user's inbox, and every sent message will just print to the console. Download the sample code, which has server-side logic that you can use as-is.

GET request

The first thing that we want to do in our sample application is display email messages from the user's inbox. Follow these steps:

1 2 3 Page 1
Page 1 of 3