Search code examples
javascriptbackbone.jsbackbone.js-collectionsbackbone-model

Adding models to collection throws error "Uncaught TypeError: Cannot read property 'idAttribute' of undefined"


I'm having an error trying to add multiple models from the server to a collection. It throws the error:

Uncaught TypeError: Cannot read property 'idAttribute' of undefined

Here is a test example which gives same error:

<script type="text/javascript" src="js/jquery.3.2.1.min.js"></script>
<script type="text/javascript" src="js/underscore.1.8.3.min.js"></script>
<script type="text/javascript" src="js/backbone.1.3.3.min.js"></script>

<script type="text/javascript">

    var Mymodel = Backbone.Model.extend({
        defaults:{
            id: null,
        },
        idAttributes: "id",
        render: function(){
            collection.add([{id:1, name: "name"},{id:2, name: "name"}])
        }
    });

    mymodel = new Mymodel();

    var mycollection = Backbone.Collection.extend({ model: mymodel });

    collection = new mycollection();

    mymodel.render();

</script>

Solution

  • The model property of the collection class should be a model constructor, not an instance.

    Backbone.Collection.extend({ model: Mymodel });
    

    The model class has a idAttribute property, singular, which is already 'id' by default.


    Putting the id attribute in the defaults isn't necessary and could lead to problems down the road.


    Other than the previous points, doing rendering within a model is bad practice. Use a view for this.

    render: function(){
        collection.add([{ id:1, name: "name" }, { id:2, name: "name" }])
    }
    

    I understand this is a test example, but if it wasn't, a model class shouldn't change a global collection instance. The whole point of classes is to scope the responsibilities to the class itself and nothing outside of it.

    Using a global like that just goes against the whole point of using Backbone.

    Minimal code needed

    var MyModel = Backbone.Model.extend({}),
        MyCollection = Backbone.Collection.extend({ model: MyModel }),
        collection = new MyCollection();
    
    collection.add([
        { id: 1, name: "name" },
        { id: 2, name: "name" }
    ]);