No discussion of a JavaScript toolkit would be complete without a mention of the AJAX and server-side communication facilities that are available. Dojo's support for server-side communication via the XMLHttpRequest (XHR) object is quite rich, and the dojo.xhrGet function is the most logical starting point, because it is the most commonly used variant. As you might have suspected,
it performs a GET request to the server. Unless you configure it otherwise, the request is asynchronous and the return type is interpreted as text. Here's an example of typical usage:

dojo. xhrGet ({
url : "/foo", Ilreturns {"foo" : "bar"}
handleAs : "json", /I interpret the response as JSON vs text load: function (response, ioArgs) t
/* success! treat response.foo just like a normal JavaScript object *1
I,
error : function (response, ioArgs) {
1* be prepared to handle any errors that occur here *1

A point wasn't made of it, but the reason that both the load and error function returns the response type is because Dojo's I/O subsystem uses an abstraction called a Dejerred to streamline network operations. The Deferred implementation was adapted from MochiKit's implementation (which was, in turn, inspired from Python's Twisted networking engine).

Name:  Server communication.jpg
Views: 237
Size:  18.7 KB

The overarching concept behind a Deferred is that it provides a uniform interface that drastically simplifies I/O by allowing you to handle asynchronous and synchronous requests the very same way. In other words, you can chain callbacks and errbacks arbitrarily onto a Deferred, regardless of whether the network I/O is in flight, threw an error or completed successfully. Regardless, the callback or errback is handled the same way. In some situations, Deferreds almost create the illusion that you have something like a thread at your disposal.

Here's an updated example of the previous dojo.xhrGet function call that showcases the dojo.Dejerred object that is returned:
~ How To Developers I
var d = dojo.xhrGet({
url : "I foo", /I returns {" foo" : "bar"}
handleAs : "json", II interpret the response as JSON instead
load : function (response, ioArgs) {
/ * success! treat response. foo just
like a normal JavaScript object *1 return response; II pass into next callback
error: function (response, ioArgs) {
1* be prepared to handle any errors that occur here *1 return response; I/pass into next errback
1* The xhrGet function just lired. We have no idea if/when it will complete in this case since it's asynchronous.
The value of d, the Deferred, right now is null since it was an asynchronous request * /
Ilgets called once load completes
d. addCallback (function (response) { 1* Just chained on a callback that
lires after the load handler with the same response that load returned. *1
d. addCallback (function (response) {
1* Just chained on another callback that lires after the one we just added *1
d. addErrback (function (response) { 1* Just added an errback that
lires after the default error handler *1
Again, the beauty of a Deferred is that you treat it as somewhat of a black box. It doesn't matter if, when or how it finishes executing. It's all the same to you as the application programmer.

Just so you're aware, sending data to the server with another HTTP method, such as POST or PUT, entails using the very same kind of pattern and works just as predictably with the dojo.xhrPost function. You even can provide a form node so that an entire form is POSTed to the server in one fell swoop or pass in raw data for those times when you need to transfer some information to the server as
part of a RESTful (Representational State Transfer-based) architecture. The dojo. toJson function may be especially helpful in serialising JavaScript objects into a properly escaped JSON string, if the protocol is something along the lines of a JSON-RPC system in which the envelope is expected to be JSON in both directions.