There has to be something simple I am missing here.
I am just learning Backbone.js and Underscore.js/Lodash and am trying to get familiar with chain.
I have the following code, which works as expected:
var ids = _.pluck(collection.where({'is_checked':true}), 'id');
I attempted to refactor this, using chain like so:
var ids = collection.chain().where({'is_checked':true}).pluck('id').value();
Why doesn’t the refactored code work? Am I using chain wrong?
Solution (details below)
Don’t use where with chain.
The merging of some Underscore methods into collections is a little imperfect. When you say
collection.some_mixed_in_underscore_method(), the collection unwraps some of the Backbone stuff behind your back so that the Underscore method is applied to the attributes inside the collection’s models; it sort of works like this:But
collection.chain()doesn’t work like that,chainjust wraps the collection’smodelsdirectly so if you do this:you’ll see that
chainis giving you an object that wraps an array of models. Your models won’t have anis_checkedproperty (i.e. there is nomodel.is_checked), they will haveis_checkedattributes though (i.e. there will bemodel.get('is_checked')andmodel.attributes.is_checked).Now we can see where everything goes wrong:
The models don’t have
is_checkedproperties. In particular, there won’t be any models whereis_checkedistrueand everything after thewhereis working with an empty array.Now that we know where things go sideways, how do we fix it? Well, you could use
filterinstead ofwhereso that you can easily unpack the models:But, your models don’t have
ids yet as you didn’t create them withids and you haven’t talked to a server to getids so you’re going to get an array ofundefineds back. If you add someids:then you’ll get the
[1,2]that you’re looking for.Demo: http://jsfiddle.net/ambiguous/kRmaD/