-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Collection length does not match models length, when fetching and parsing data with duplicate ids #2976
Comments
Your model ids should be unique per model, and if the server is returning multiple objects with the same id, that seems like a bug on the part of the server. Not much Backbone can (or should) do about it. |
But that error seems incorrect... |
Right -- I understand that there's a bug on the server. I was just wondering if there is a better way for Backbone handle the error. I've noticed that if you attempt to If it were up to me, I would prefer that adding duplicate models would throw an error, though I imagine this would be a breaking change for many users. |
That's how it used to be ... and this behavior was an "enhancement" ;)
Quite so. |
So moral of the story is that If I had to hazard a guess at this point, I'd say it's because of this line and the new idAttribute parsing. The server response hasn't been parsed yet to expose the models' ids and thus the The algorithm is still incorrect with duplicates on non-nested attributes too ( |
I updated my spec to use the Is the intended behavior to silently reject the duplicate model, or should If you want to go this route, I wrote a couple of specs for the expected behavior. |
09e0cb3 dropped support for this case. I think we need a // Default
generateId: function (attrs) {
return attrs[this.idAttribute];
}
// For @eschwartz's test case...
generateId: function (attrs) {
return attrs.nested.id;
} Then instead of using |
Definitely. Relying on the data to be parsed before it's passed to |
@akre54 working up a quick PR, so we can get into details there. |
That still doesn't solve the problem of duplicate models being passed in the same |
Fix #2976 Do not add multiple models with same `id`
Re #2976 Allow `id` values to be generated from a function given attrs
One note here - I may be missing it, but it seems that if your model is defined as a function on your collection, you still wont have access to the idAttribute of that model until its called - correct? How can targetProto be defined before the model function is called and returned? |
@chiplay Check out https://github.com/jashkenas/backbone/pull/3042/files for an example of setting |
Thanks @caseywebdev I dont think I can set the idAttribute on the Collection, since the idAttribute is different for both Model types on the polymorphic model. I'm not sure by looking at it how I can use generateId to produce the correct id - can you explain or point me the right direction? Thanks! |
@caseywebdev ahhh - got it - little slow today. I just need to set the generateId method on my collection and then use the attrs to return the correct Id - brilliant! |
var TypeA = Backbone.Model.extend({idAttribute: '_a'});
var TypeB = Backbone.Model.extend({idAttribute: '_b'});
var Poly = Backbone.Collection.extend({
model: Backbone.Model.extend({
constructor: function (attrs, options) {
var model = attrs.type === 'a' ? TypeA : TypeB;
return new model(attrs, options);
},
generateId: function (attrs) {
return (attrs.type === 'a' ? TypeA : TypeB)
.prototype.generateId(attrs);
}
})
}); Let me know if that helps. Keep in mind |
Duplication Steps
id
from an arbitrary response object attributeTypeError: Cannot read property 'cid' of undefined
See Spec (failing) for mismatched collection length for a failing spec, duplicating this issue.
Expected Behavior
The root issue is clearly that the API is returning duplicate objects. However, I'm wondering if there might be a better way for Backbone to handle this situation, which would make the problem easier to trace.
What is the default behavior when adding a model to a collection with the same id as an existing model in the collection? I would expect an error to be thrown.
The text was updated successfully, but these errors were encountered: