Backbone: idAttribute is undefined for modelId method if model define as function.

Created on 9 Dec 2019  ·  10Comments  ·  Source: jashkenas/backbone

duplicate

Most helpful comment

I just merged the old https://github.com/jashkenas/backbone/pull/3966 PR, after resolving conflicts. Let me know if it gives you any trouble...

All 10 comments

I don't follow. how is model defined as a function?

I actually ran into this problem (or something similar) yesterday.

You can define a model function on a collection for polymorphic model creation.

When calling .add on your collection, the Backbone code tries to call .prototype.idAttribute on the model attribute, but if you've defined the model function as a ES2015 class method then it doesn't have a prototype attribute.

See here: https://github.com/jashkenas/backbone/blob/75e6d0ce6394bd2b809823c7f7dc014ddb6ae287/backbone.js#L1102

So for example, this will cause the issue:

const Library = Backbone.Collection.extend({
    model () {
       // stuff goes here
   }
});

If you specify it like this, then it the problem goes away:

const Library = Backbone.Collection.extend({
    model: function () {
       // stuff goes here
   }
});

I actually ran into this problem (or something similar) yesterday.

You can define a model function on a collection for polymorphic model creation.

When calling .add on your collection, the Backbone code tries to call .prototype.idAttribute on the model attribute, but if you've defined the model function as a ES2015 class method then it doesn't have a prototype attribute.

See here:

https://github.com/jashkenas/backbone/blob/75e6d0ce6394bd2b809823c7f7dc014ddb6ae287/backbone.js#L1102

So for example, this will cause the issue:

const Library = Backbone.Collection.extend({
    model () {
       // stuff goes here
   }
});

If you specify it like this, then it the problem goes away:

const Library = Backbone.Collection.extend({
    model: function () {
       // stuff goes here
   }
});

Thank you for problem detailed description!

But your answer is not resolve problem for idAttribute.

On add new model reference not added. Therefore you cant get new model by id.

image

Workarond - added model.prototype.idAttribute the same as on the model.

I think the issue is that model on a Collection is defined as: Override this property to specify the model class that the collection contains. This API does not support model being defined as a function.

@paulfalgout the backbone docs for Collection.model specify you can set a function as the model. That this is not possible with the model () syntax (instead of model: function()) seems like a bug to me or at least extremely confusing.

Yes, I linked to the relevant part of the docs in my original message.

See here: https://backbonejs.org/#Collection-model

@PavelKoroteev: Looks like our problems are related, but not the same.

Here's what I'm talking about (pasted from the console):

collection = new (Backbone.Collection.extend({  model (attrs, options) { return new (Backbone.Model.extend({ idAttribute: 'customId' }))(attrs, options)}}));

child {length: 0, models: Array(0), _byId: {…}}

collection.add({ customId: 'id.1' });
backbone.js:1102 Uncaught TypeError: Cannot read property 'idAttribute' of undefined
    at child.modelId (backbone.js:1102)
    at child.get (backbone.js:997)
    at child.set (backbone.js:872)
    at child.add (backbone.js:814)
    at <anonymous>:1:12

I think the issue is actually the same. And also the same as https://github.com/jashkenas/backbone/issues/4203

using model: function(attrs, options) would create a prototype which would not have idAttribute and it would fall back to id so it would "work"

You're correct the polymorphic model is documented. _but_... it hasn't supported idAttribute or es6-type methods because of this line with model.prototype for quite a while.

It seems https://github.com/jashkenas/backbone/pull/3966 is a fix of sorts :-/

Seeing a PR from 2016 languishing and not getting merged (or rejected in favour of something better) basically discourages me from even trying to make a PR to fix this issue.

From what I can tell, Backbone is pretty much dead.

Like others have done as well, I've created a fork, mine is called Skeletor, which I'll use to update my Backbone code to more modern APIs and standards and then I'll gradually move away to something better.

I just merged the old https://github.com/jashkenas/backbone/pull/3966 PR, after resolving conflicts. Let me know if it gives you any trouble...

Was this page helpful?
0 / 5 - 0 ratings