Ajax in Action. Chapter 6: The User Experience | 3 | WebReference

Ajax in Action. Chapter 6: The User Experience | 3

To page 1To page 2current page

Ajax in Action. Chapter 6: The User Experience

6.2.2 Handling updates from other users

Our planetary viewer application allows more than one user to log in at once, so presumably other users may be editing data while we are. Each user would presumably like to be informed of changes made by other users more or less as they happen. Most Ajax applications will involve more than one browser sharing a domain model, so this is again a fairly common requirement.

We can modify our XML response, and the Command queue object, to cope with this situation in the following way. For each update to the server-side model, we generate a timestamp. We modify the server-side process that handles updates to also check the domain model for recent updates by other users, and attach them to the response document, which might now look like this:

Alongside the <command> tags, which are identified by the ID of the Command object in the sent queue, there is an <update> tag, which in this case denotes that the distance from the sun of Venus has been set to a value of 0.76 by another user called Jim. We have also added an attribute to the top-level tag, the purpose of which we explain shortly.

Previously, our command queue sent requests to the server only if there were commands queued up. We would need to modify it now to poll the server even if the queue were empty, in order to receive updates. Implementing this touches upon the code in several places. Listing 6.1 shows the revised CommandQueue object, with the changes in bold.

We’ve added quite a bit of new functionality here. Let’s step through it. First, we’ve introduced a global lookup of command queue objects . This is a necessary evil given the limitations of the setInterval() method, which we’ll discuss shortly. The constructor takes a unique ID as an argument and registers itself
with this lookup under this key.

The CommandQueue constructor now takes two other new arguments . onUpdate is a Function object that is used to handle the <update> tags that we introduced into our response XML. freq is a numerical value indicating the number of seconds between polling the server for updates. If it is set, then the constructor initializes a call to the repeat() function , which uses JavaScript’s builtin setInterval() method to regularly execute a piece of code. setInterval() and its cousin setTimeout() accept only strings as arguments under Internet Explorer, so passing variable references directly into the code to be executed is not possible. We use the global lookup variable and the unique ID of this queue to develop a workaround to this problem in the repeat() method. We also keep a reference to the repeating interval, so that we can stop it using clearInterval() in our unrepeat() method .

In the fireRequest() method, we previously exited directly if the queue of commands to send was empty. That test has been modified now so that if an onUpdate handler is set, we will proceed anyway and send an empty queue in order to fetch any <update> tags waiting for us. Alongside our own edited data, we send a timestamp telling the server the date that we last received updates , so that it can work out to send us relevant updates. This is stored as a property of the command queue and set to 0 initially.

We pass these timestamps as UNIX-style dates, that is, the number of milliseconds elapsed since January 1, 1970. The choice of timestamp is based on portability. If we chose a date format that was easier to read, we would run into issues with localization, differences in default formats across platforms and languages, and so on. Getting localization right is an important topic for Ajax applications, since the application will be exposed to users worldwide if it is on the public Internet or the WAN of a large organization.

In the onload() function, we add the code required to update the last updated timestamp when a response comes in and to parse <update> tags . The onUpdate handler function is called with the command queue as its context object and the <update> tag DOM element as the sole argument.

In the case of our domain model of the solar system, the update handler function is shown in listing 6.2.

The attributes in the <update> tag give us all the information that we need to update the domain model on the JavaScript tier. Of course, the data coming from the server may not be correct, and we need to take some action if it isn’t. In this case, we have fallen back on an alert() statement compounding the problems that were discussed in section 6.2.1.

We’ve added quite a bit more clever code to our command queue object in the process of handling updates from other users, including passing timestamps between the client and web tiers, and adding a pluggable update handler function. Eventually we come full circle to the issue of informing the user of changes and asynchronous updates as they take place. In the next section, we look at our options for presenting this information to the user in a more workable fashion, and we’ll factor out that pesky alert() function.

Written by Dave Crane and Eric Pascarello with Darren James and reproduced from "Ajax in Action" by permission of Manning Publications Co. ISBN 1932394613, Copyright 2005. All rights reserved. See http://www.manning.com for more information.

To page 1To page 2current page

Created: March 27, 2003
Revised: October 31, 2005

URL: http://webreference.com/programming/ajax/1