How to override Backbone.sync?
I'm trying out Backbone.js, and one of the things I'm trying is to make a call to a remote API, so I need to be able to override Backbone.sync, as I understand the documentation.
There isn't an example of how to do that in the documentation itself, and there doesn't appear to be a google group for Backbone... can someone point out an example for doing this?
Solution 1:
Take a look at this annotated source example where they overwrite Backbone.sync
with a localstorage alternative
backbone-localStorage
Basically Backbone.sync should be a function that takes 4 arguments:
Backbone.sync = function(method, model, options) { };
You need to fire either options.success
or options.error
depending on whether the method
succeeded. The methods are in the format:
-
"create"
: expected that you create the model on the server -
"read"
: expected that you read this model from the server and return it -
"update"
: expected that you update the model on the server with the argument -
"delete"
: expected that you delete the model from the server.
You need to implement those 4 methods and define whatever you want for your "server"
Of course these are only the things that Backbone.sync
must implement. You may implement more methods
and you may pass more paramaters back to success
but it's best not to do this.
It's best to make sure it does the same as Backbone.sync
does currently so that your programming to an interface rather then an implementation. If you want to switch out your modified Backbone.sync
for say the localStorage one you won't have to extend it yourself to match your extended Backbone.sync"
[Edit]
Also do note that you can use multiple implementations of sync
. Every reference to Backbone.sync
is actaully (this.sync || Backbone.sync)
so you just have to do something like:
var MyModel = Backbone.Model.extend({
...
"sync": myOwnSpecificSync,
...
});
Backbone.sync
is just the default global one that all models use unless the models have a sync
method specifically set.
Solution 2:
I know this answer is a bit too late, and the answer from @Raynos is great, but I did it a bit differently, and maybe it would be useful for you or for any other person trying to use an API with Backbone.
Instead of overriding Backbone.sync, I overrided Backbone.ajax, because it's where the ajax request is made.
Here's an example :
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
Backbone.ajax = function() {
var args = Array.prototype.slice.call(arguments, 0);
// Here, I add the OAuth token (or any other token)
// But before, I check that data exists, if not I add it
if (args[0]['data'] === undefined) {
args[0]['data'] = {};
}
args[0]['data']['token'] = 'any_api_token_here';
return Backbone.$.ajax.apply(Backbone.$, args);
};
Solution 3:
I typically need to override backbone's sync
method when I need to only sync certain attributes. A typical implementation looks like this:
sync: function (method, model, options) {
options.data = _.pick(this.attributes, 'foo', 'bar', 'baz');
return Backbone.sync.call(this, method, model, options);
}