Wrapping $.ajax In A Thin “Command” Framework For Backbone Apps
A large number of my recent client applications, built on Backbone, have been using straight jQuery AJAX calls. Sometimes its in combination with Backbone’s persistence method, but other times I end up using AJAX calls in place of Backbone calls.
Now I don’t think that there’s anything wrong with Backbone’s “save”, “fetch” and “destroy” methods. They’re quite handy, and very well done. The deciding factor in using them is whether or not my application is CRUD-y or not. That is to say, many of my recent apps are taking more of a command approach to user interaction and data updates. Instead of just having simple Create, Read, Update and Delete forms on my apps, I tend to have smaller and more focused commands that are called.
Executing Commands vs Making AJAX Calls
As a result of all this, I end up using $.ajax a lot… and it’s getting really ugly and obnoxious seeing this all over my code:
Not only is this ugly when you repeat the $.ajax calls all over the code, but it doesn’t really give the semantic benefit of knowing what the code is really doing. I’m not just making a call across an AJAX connection. I’m trying to execute a command – I’m trying to do something important, and I want my code to reflect that.
So I wrapped up my $.ajax calls in a thin “command” wrapper for my current client app (built with Backbone of course), and ended up with this instead:
Looking at this in comparison to the original $.ajax calls, there are a few less lines of code. Since I have a thin wrapper around the ajax calls and setup, I can make a few assumptions about the calls and provide a little bit of default configuration.
I can also move the registration of commands somewhere other than the execution of the commands, which is a huge win for readability and organization of the code when it comes time to execute a command.
Of course the handling of events for success, error and completed doesn’t give me any advantage over $.ajax and deferred objects. But the big benefit here and why I don’t mind the thin wraper around the done/fail/always deferred methods, is the semantic value of executing a named command vs configuring an ajax call.
And before you go in to a “semantics are not important” lapse of sanity, just think a little about this line that I once heard from Sharon Cichelli:
“Semantics will continue to be important until we learn to communicate in something other than language.“
Implementing The Command Structure
This implementation relies on Backbone, Underscore and jQuery, so it’s really only useful in Backbone applications at this point. It’s also important to note that this code is not unit tested at all. I’m using it in my current client application and it is functional for me, but I don’t recommend taking this code as a great implementation, yet. I have plans on turning this into a real plugin, with full testing around it. But like most of my plugins and libraries, it started out as a quick hack in order to get something cleaned up in one of my applications.
There ar ea couple of things you’ll want to note in this code:
The call to “register” a command stores the configuration that you provide. The call to “get” a command creates a new command instance and hands it back to you. This is done so that you can have single-use command objects and not have to worry about unbinding events from the command after it has completed. If I held on to a single command instance and just handed that back to you, you would be responsible for unbinding the event handlers after executing the command.
The wrapper events for “success”, “error”, and “complete” also don’t guarantee to fire if you subscribe to them after the command has been executed. So, it’s important to set up your event handlers before calling .execute on the command object.
I’ve also extracted the “getUrl” method specifically because I need to provide a very custom implementation of this method in my client’s application. I have another plugin that I’m looking at writing, which handles storage and retrieval of URLs in my Backbone apps, including :token replacement in the urls … but that’s another blog post and another plugin to write.
A Timed Polling Mechanism
One of the more interesting things I’m doing with this is using it as a timed polling mechanism. I set up a command and then I wrap the commands “execute” function in another method that I can call from a setTimeout. When the command executes, I check the response. If I find the data I need, I move on. If I don’t find the data I need, I call the wrapper function again, inside of a setTimeout.
There’s lot of fun little tricks you can do with a simple object wrapper like this, that would be a little more cumbersome and awkward when directly using $.ajax.