Crystal
Crystal

Reputation: 29458

this model is undefined when trying to add object to backbone collection

I was wondering if there was anything I should keep in mind when using a backbone collection? I basically have a model, and my collection is defined as:

LibraryPreps = (function () {
    return Backbone.Collection.extend({
        model: LibraryPrep,
        url: '/api/platform',
        initialize: function (models, options) {

        }
    });
})();


LibraryPrep = (function () {
    return Backbone.Model.extend({

        defaults: {
            name: '',
            platform: '',
        },
        initialize: function () {
            return this;
        }
    });
})();

nothing fancy about them. When I create a LibraryPrep and log it, it looks like the data I want. But when I try adding it to the collection, I get this error:

TypeError: this.model is undefined
followed by this line of code:
this._idAttr || (this._idAttr = this.model.prototype.idAttribute);

I'm basically doing this:

var libPreps = new LibraryPreps();

            _.each(libraries, function (library) {
                console.log("POPULATE LIBRARY PREP");
                console.log(library);
                var tempLibPrep = new LibraryPrep(library);
                console.log(tempLibPrep);

                libPreps.add(tempLibPrep);    // why aren't you working?!
            });

I used a collection somewhere else before, and I never seemed to have a problem with it. I am pretty new to web though so maybe there is just something I'm not thinking of. Any thoughts? Thanks in advance :-.

Upvotes: 0

Views: 1488

Answers (2)

mu is too short
mu is too short

Reputation: 434665

Have a look at LibraryPreps.prototype and you'll see where you're going wrong. First of all, your real code has to look more like this or you'll be getting ReferenceErrors:

var LibraryPreps = (function () { ... })();
var LibraryPrep  = (function () { ... })();

When the anonymous function which produces LibraryPreps executes, LibraryPrep will be undefined because it isn't assigned a value until later. If you do this:

var LibraryPreps = (function () {
    return Backbone.Collection.extend({
        model: LibraryPrep,
        //...
    });
})();
var LibraryPrep = (function () {
    return Backbone.Model.extend({ /*...*/ });
})();
console.log(LibraryPreps.prototype);

you'll see the LibraryPreps.prototype.model is undefined in the console. Demo: http://jsfiddle.net/ambiguous/y8cja/

The Backbone.Collection.extend call (with or without the anonymous self-executing function wrapper) is forcing the LibraryPrep to be evaluated when extend is called so you end up building a collection "class" with an undefined model property. Then, inside Backbone, it will be looking for the idAttribute of the collection's model and you get your error.

Fix the order of your definitions so that things are defined before you use them:

var LibraryPrep  = (function () { ... })();
var LibraryPreps = (function () { ... })();

and you'll have better results.


As Loamhoof notes in the comments, your code works fine with the current version of Backbone (1.0.0) and I can't find this:

this._idAttr || (this._idAttr = this.model.prototype.idAttribute);

anywhere in the 1.0.0 source. Presumably you're using an older version of Backbone whose Collection#add method needs to know the idAttribute property of its model.

Upvotes: 2

Scott Puleo
Scott Puleo

Reputation: 3684

Have you tried to add the models directly to the collection?

libPreps.add(libraries); 

http://backbonejs.org/#Collection-add

addcollection.add(models, [options]) Add a model (or an array of models) to the collection, firing an "add" event. If a model property is defined, you may also pass raw attributes objects, and have them be vivified as instances of the model. Pass {at: index} to splice the model into the collection at the specified index. If you're adding models to the collection that are already in the collection, they'll be ignored, unless you pass {merge: true}, in which case their attributes will be merged into the corresponding models, firing any appropriate "change" events.

Upvotes: 0

Related Questions