Monday, January 23, 2006

Ajax in practice

In my research of using AJAX, I've run across plenty of nice examples. Most of the examples consist of the basics of building and using an XMLHttpRequest such as:

function createRequestObject() {
var ro;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer"){
ro = new ActiveXObject("Microsoft.XMLHTTP");
}else{
ro = new XMLHttpRequest();
}
return ro;
}
var http = createRequestObject();

The use that XMLHttpRequest object to submit the request to the back-end server such as:

function sendRequest(action) {
http.open('get', 'ajaxHandler.php?action='+action);
http.onreadystatechange = handleResponse;
http.send(null);
}

And finally some function to update the browser page based on the result:

function handleResponse() {
/* The XMLHttpRequest object has a property called readyState with several states:
0: Uninitialized
1: Loading
2: Loaded
3: Interactive
4: Finished
*/
if(http.readyState == 4){
var response = http.responseText;
document.getElementById('divName').innerHTML = response;
}
}

That's all well and good, but is seems like a misuse of an XMLHttpRequest to send a plain text (or HTML) response. We have a perfect opportunity to separate presentation from data and everyone seems to mash them together on the back-end instead of letting the browser handle the rendering. At least the example here demonstrates using the responseXML property of the XMLHttpRequest object instead of only the text response which is nice.

One of the worst abuses that I've encountered so far seems to b e the Google Suggest implementation. In my past research of AJAX I ran across this excellent piece by Chris Justus about how Google used AJAX to implement Google Suggest. I must say, I'm disappointed with how the folks at Google did that. As Chris demonstrates, they actually return a JavaScript snippet which it then invoked by the browser to add the search suggestions.

Sample returned value:

sendRPCDone(frameElement, "fast bug",
new Array("fast bug track", "fast bugs", "fast bug", "fast bugtrack"),
new Array("793,000 results", "2,040,000 results", "6,000,000 results", "7,910 results"),
new Array(""));

The actual sendRPCDone method is previously loaded in the web page, but they instruct the browser to invoke it was it gets the response. Obviously it works, and is very fast, but the data just seems too bound to the implementation. Why not just return the data in a format that can be used in this page, and possibly other functions? Something like:

<suggestions>
<search>fast bug</search>
<suggestion>
<value>fast bug track</value>
<occurs>793,000</occurs>
</suggestion>
<suggestion>
<value>fast bugs</value>
<occurs>2,040,000</occurs>
</suggestion>
<suggestion>
<value>fast bug</value>
<occurs>6,000,000</occurs>
</suggestion>
<suggestion>
<value>fast bugtrack</value>
<occurs>7,910</occurs>
</suggestion>
</suggestions>

No comments: