Proof of Concept: Event-Driven AJAX Chaining

Introduction

I had one of those “aha” moments last night as I was falling asleep. I hacked up this example during my lunch break as a “proof of concept”. I was wondering, Can you have an AJAX call in a chain without halting execution, throwing errors or losing the response?

Idea

The main idea is really easy- if your AJAX call is ready you execute right away, otherwise you listen (or bind) for the AJAX call to finish. Then when the AJAX call finishes you notify (or trigger) all listeners of the event. It basically let’s you write code as you always have been before all this event-driven stuff, but the event-driven triggers and bindings are baked into the code keeping your code extremely elegant.

Example of Event-Driven AJAX Chaining

Now maybe jQuery uses this technique in their $.load and $.get but I typically use their lower level $.ajax function so this would be what I typically write:

$.ajax({
   url: 'signup.php',
   data: {form: formData},
   success: function(response) {
      showLogin();
   }
});

Instead of that mess, we can write:

AJAX("signup.php", {form: formData}).success(showLogin);

AJAX Class Implementation

var AJAX = function(url, args) {
// Lets you do AJAX(...) or new AJAX(...)
if (!(this instanceof arguments.callee)) {
   return new arguments.callee(url, args);
};
if(!url) {
   return this;
}
this.url = url;
this.args = args;
this.init();
return this;
};
// Methods
AJAX.prototype = {
   init : function() {
      this.isReady = false;
      this.response = null;
      var _AJAX = this;
      $.ajax({
         url: _AJAX.url,
         type: 'GET',
         dataType: 'html',
         data: this.args,
         // Trigger isReady for listeners to respond
         success: function(response) {
            _AJAX.isReady = true;
            _AJAX.response = response;
            $(_AJAX).trigger('isReady', [response]);
         }
      });
      return this;
   },
   success : function(context, callback) {
      if(!context && !callback) return this;
      if(!callback) {
      callback = context;
      context = window;
      }
      // If we already ready, call the callback
      if(this.isReady) {
      if(typeof callback === "string") {
         context[callback](this.response);
      } else if(typeof callback === "function") {
         callback.call(null, this.response);
      }
      // Otherwise listen for success to be ready and call
      } else {
         $(this).bind('isReady', function(e, response) {
            $(this).unbind('isReady');
            return this.success(context, callback);
         });
      }
      return this;
   }
};

Extension

Now this is clearly the beginning. This code really needs to be refactored – we have to reimplement the event-driven logic in each method we write- I’m certain we wouldn’t have to do this each time with some sort of AJAX.extend(‘isReady’, function() {…}) with a callback function. Those this example isn’t all that impressive because we are using success, we could have any arbitrary event such as AJAX(‘createForm.php’).show(showForm).

Conclusion

Now I haven’t done any research and maybe this technique is obvious, but I think this is a good way to abstract AJAX programming from the typical web developer and keep AJAX calls clean without worrying about when we’re going to get a response from the server. I’d be curious to hear your thoughts!