Search code examples
design-patternsbackbone.js

Backbone Model.sync proxy why is the second parameter (model) is obligatory


I'm curious with contrary intuitive behavior of Model.sync function.

The second argument for sync is the model, and when it is Backbone.sync it does make sense. But when it behaves as a proxy:

var MyModel = Backbone.Model.extend({baseUrl})
var myModel = new MyModel({id})
console.log(myModel.url()) // will issue baseUrl + id path
myModel.sync(method, myModel)

It is bit of a superfluous to pass same model on which you called sync.

In case you will not pass it the very unfriendly error will pop up:

backbone.js:1907 Uncaught Error: A "url" property or function must be specified

And this is done on design. As when you have close look at docs they clearly state the second parameter to be obligatory.

I'm trying to understand what is the reasoning behind not making it bit flexible, and pass this model through on the library level vs making it on your own?

Something like this, very silly example to demonstrate what I'm up to:

// Proxy `Backbone.sync` by default -- but override this if you need
// custom syncing semantics for *this* particular model.
sync: function() {
  var args = arguments.splice(2, 0, this); // << make second attribute correspond to the this model
  return Backbone.sync.apply(this, args);
},

Clarification:

The documentation on Model.sync says

sync model.sync(method, model, [options]) Uses Backbone.sync to persist the state of a model to the server. Can be overridden for custom behavior.

So in my case I am trying to sync model using 'patch' method with the following steps:

a. Update model with data
b. Sync this data with sync method

 this.model.set(data)
 this.model.sync('patch', this.model)

Solution

  • The sync() method is kind of private (or better: protected), the programmer wants to use fetch(), save() and destroy().

    But since sync() strictly defines how to "crud" (create, read, update delete); that AJAX is used, how requests are made and parsed, it has to provide a way to allow programmers to change that behaviour. This is what they mean, when they say

    sync model.sync(method, model, [options]) Uses Backbone.sync to persist the state of a model to the server. Can be overridden for custom behavior.

    And due to that Backbone must define some interface for sync() so that all the public methods can pass the one data source, the model.


    Note that there might be a suitable patch method, since save() takes the option patch: true. See the source in line 645

     var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');