Question

In the O'Reilly 'Developing backbone.js applications' example for overriding Backbone.sync, there is the following logic to run example findAll() vs find() methods:

case 'read':
  if (model.attributes[model.idAttribute]) {
    return MyAPI.find(model, success, error);
  } else {
    return MyAPI.findAll(model, success, error);
  }
}

Running fetch() on a Collection causes the following error: model.idAttribute is undefined

That's because the parameter model contains a collection when myCollection.fetch() is called. So it doesn't contain idAttribute.

It seems to me that simply testing for the existence of model.idAttribute would suffice to differentiate between a Model and a Collection, in order to switch between find() and findAll().

Am I missing something else here? This is an authoritative resource.

Was it helpful?

Solution

The code fix should probably be something like

case 'read':
if (model.idAttribute) {
    if (model.attributes[model.idAttribute]) {
        return MyAPI.find(model, success, error);
    }
} else {
    return MyAPI.findAll(model, success, error);
}

You need to test for both, because the model might define which attribute is it's id with the idAttribute value, but the actual id value might not be present. In other words, if the model instance you receive is

{
    idAttribute: "myId",
    name: "test"
}

You can't call your find method, because you have to id value to use in your query (i.e. myModel.get("myId") wont return anything).

OTHER TIPS

You can try instanceof :

case 'read':
  if (model instanceof Backbone.Model && model.idAttribute) {
    return MyAPI.find(model, success, error);
  } else if (model instanceof Backbone.Collection) {
    return MyAPI.findAll(model, success, error);
  } else {
    // the model have no idAttribute
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top