I know there's plenty of ways to do this... but why isn't this approach working?
var selected = this.collection.where({checked: true});
var mapped = _.map(selected, Backbone.Model.prototype.toJSON.call);
this.$el.html(this.template(mapped));
Error is Uncaught TypeError: undefined is not a function
Is there a more succinct way?
EDIT This did what I wanted...
var mapped = _.invoke(selected, Backbone.Model.prototype.toJSON);
EDIT 2 @nikoshr made it better.
var mapped = _.invoke(selected, 'toJSON');
Have a look in _.map
source code, you will see, as of version 1.5.1
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results.push(iterator.call(context, value, index, list));
});
return results;
};
which means that for each object in selected
, you will end with Backbone.Model.prototype.toJSON.call.call
and an unspecified context, which probably isn't what you want.
The simplest way to call toJSON
on each model would be to use _.invoke
:
invoke _.invoke(list, methodName, [*arguments])
Calls the method named by methodName on each value in the list.
Applied to your case :
var mapped = _.invoke(selected, 'toJSON');
And a demo
var c = new Backbone.Collection([
{id: 1, checked: true},
{id: 2, checked: false},
{id: 3, checked: true}
]);
var selected = c.where({checked: true});
var mapped = _.invoke(selected, 'toJSON');
console.log(mapped);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>