CLOSE ×
Get in Touch
Thank you for your interest! Please fill out the form below, and I will do my best to get back to you.

Thank you! Your submission has been received!

Oops! Something went wrong while submitting the form.

BackboneJS: Dynamic Override of sync() Method

Garth Henson
|
JavaScript
|
27 Jun 2012

As with any good solution, there needs to be a valid problem you’re trying to solve. In this case, I ran into a challenge at work and wanted to share the concepts of what I needed to accomplish in case anyone else has run into similar troubles.

I was assigned the task of integrating a new UI with a preexisting backend API, which is really not that big of a deal in and of itself. However, as I wanted to use BackboneJS as our client MVC framework and the API was by no means RESTful nor consistent, I quickly became aware that I would need to manually override the sync() method of nearly every one of my models in order to have things function properly. Again, in and of itself, this is not a problem, but working in an environment where maintenance and change are the rule, I wanted to figure out a way to extract the customization in such a way as to be extremely easy to manage.

In order to solve this problem, I decided to figure out a way to dynamically load the appropriate sync() methods from outside the models themselves, keeping the maintenance of the changeable API in its own layer. By the time I figured out a clean way to do this, I was amazed at how easily BackboneJS supported it. I had found many, many articles on how to manually override the default call to Backbone.sync(), but nobody really discussed how to do this dynamically across multiple models, so I wanted to share that with you.

Step 1: Create a Base Application Model

We first need to understand the inheritance model that BackboneJS supports. By creating a base model from which we will extend all our others, we can easily build a custom behavior to override our methods. In this case, I simply have the parent (or base) model checking a Sync namespace for the existence of an override during initialization.

Remember that each model that extends this MyApp.Model will then inherit this behavior as well, but we can specify the classname attribute on each of the child elements to discover the appropriate sync() method, if one exists.

Step #2: Extend Base Model

For this example, we will use our base model to create a Person model. By extending from our base application model rather than the Backbone.Model, we assure that it will look for overrides to its sync() method.

Notice that for this example, the only requirement for making the override discoverable is the classname attribute that the inherited initialization logic will be using. With this simple model created, we can now separately define our override and test it out!

Step #3: Defining Overrides in Context

As the code stands now, you could instantiate a new Person(), and it will not behave any differently than a standard BackboneJS model. By design, this pattern will leave all native behavior in place unless you define an override for the current context. With this behavior, when you update your API to full REST support in the future, you can simply remove your overrides as those models are supported, and they will simply continue to work.

Now, let’s build a simple override for our Person model, taking into account the Backbone.sync API we are overriding.

Since we are binding our overrides to a namespace, we can actually have overrides in their own files or in whatever structure works for your application, though you should always look to compile and minify your JavaScript for production rather than having individual files.

Conclusion

While this post is geared specifically toward the sync() method, the pattern could easily be followed for any dynamic discovery of overrides you may need within your implementation of BackboneJS. So, how do we test the code we have written? Per the BackboneJS API, sync() is called as a deferred method for both fetch() and save() calls. So, all we need to do to test our new override is create a new Person and run one, or both, of those methods on it.

I hope this helps some of you save time and effort in creating the most dynamic and usable web applications around!

Garth Henson
Garth is as a lead engineer at The Walt Disney Company, specializing in JavaScript applications.

Recent Blog Posts

Let's Work Together
Contact Me