Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

_.bindAll(this) and Uncaught TypeError: Cannot read property 'idAttribute' of undefined in backbone-relation.js

I have two models (User and Task) which are instances of Backbone.RelationalModel.

The relation about these two models is the following:

// Task model

    var Task = Backbone.RelationalModel.extend({

        relations: [
            {
                type: 'HasOne',
                key: 'user',
                relatedModel: User
            }
        ],

        urlRoot: 'someUrl'

    });

Then I have one collection which code looks like this:

var FollowerCollection = Backbone.Collection.extend({
    initialize: function () {
         _.bindAll(this);
    }
    model: User
});


var User = Backbone.RelationalModel.extend({

});

When I make a fetch on FollowerCollection I get the following error:

 Uncaught TypeError: Cannot read property 'idAttribute' of undefined

on the line 1565 of backbone-relation.js of backbone-relation version 0.5.0


Here a piece of code of backbone-relation.js

if ( !( model instanceof Backbone.Model ) ) {
    // Try to find 'model' in Backbone.store. If it already exists, set the new properties on it.
       var existingModel = Backbone.Relational.store.find( this.model, model[ this.model.prototype.idAttribute ] );

The problem is related to _.bindAll(this) because if I comment it, it works properly.
Why? Any ideas?


like image 893
Lorraine Bernard Avatar asked Jun 29 '12 09:06

Lorraine Bernard


1 Answers

Removing the _.bindAll does work.

It's a shame, because it's a really handy function. It must interact with some part of Backbone badly. I'm on v9.10

I use this method all the time, and issues only come up sometimes (like when you want to do a bulk add to a collection).

For me, The problem was in this Backbone.js method:

// Get a model from the set by id.
get: function(obj) {
    if (obj == null) return void 0;
    this._idAttr || (this._idAttr = this.model.prototype.idAttribute);
    return this._byId[obj.id || obj.cid || obj[this._idAttr] || obj];
},

The code fails at this.model.prototype because prototype is undefined. What? Ya. For reals.

The problem is that when _.bindAll is called, it binds all properties of the collection, as @jakee says. This seems to include Collection.model, which is a bug I think.

The solution is to bind individual methods until this is fixed.

There's an existing, but closed issue on github: https://github.com/documentcloud/backbone/issues/2080 Seems like the current maintainers don't like the method, but I don't understand why.

like image 135
SimplGy Avatar answered Oct 21 '22 22:10

SimplGy