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

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

The relationship to these two models is as follows:

 // Task model var Task = Backbone.RelationalModel.extend({ relations: [ { type: 'HasOne', key: 'user', relatedModel: User } ], urlRoot: 'someUrl' }); 

Then I have one collection whose code looks like this:

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

When I make a selection on a FollowerCollection, I get the following error:

  Uncaught TypeError: Cannot read property 'idAttribute' of undefined 

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


Here's the code snippet 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 with _.bindAll(this) , because if I comment on it, it works correctly.
What for? Any ideas?


+6
source share
2 answers

Removing _.bindAll works.

This is a shame because it is a really handy feature. It must interact poorly with some part of the Highway. I'm on v9.10

I use this method all the time, and problems arise sometimes (for example, when you want to make a bulk addition 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 does not work with this.model.prototype , because the prototype is undefined. What kind? Ya. For reals.

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

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

There is an existing but closed issue on github: https://github.com/documentcloud/backbone/issues/2080 It seems that current maintainers don't like the method, but I donโ€™t understand why.

+3
source

As my project is really big, I had to create my own bindAll. Here you have the code, it works with the latest versions. I bind all the properties of the "this" instance, except those that have a prototype with properties, for example this.model in the collection

https://gist.github.com/patrixd/8025952

  //bindAll from underscore that allows 1 argument to bind all the functions from the prototype, //or if there are more arguments they will be the only binded _.originalBindAll = _.bindAll; _.bindAll = function (that) { var funcs = Array.prototype.slice.call(arguments, 1), validKeys = [], fn; if (funcs.length == 0) { for (var i in that) { fn = that[i]; if (fn && typeof fn == "function" && (!fn.prototype || _.keys(fn.prototype).length == 0)) validKeys.push(i); } _.originalBindAll.apply(_, [that].concat(validKeys)); } else _.originalBindAll.apply(_, arguments); 

};

0
source

Source: https://habr.com/ru/post/919314/


All Articles