Using Underscore Method 'find' on a Backbone Collection

25,518

Solution 1

Backbone collection implements many of the Underscore functions, so you could do this:

var found = myCollection.find(function(item){
        return Number(item.get('tranId')) === tranId;
});

Also to debug if the values are not what you expect try:

var found = myCollection.find(function(item){
        console.log('Checking values', item, item.get('tranId'), tranId);   
        return Number(item.get('tranId')) === tranId;
});

Solution 2

A more simple one:

var found = myCollection.findWhere({'tranId': tranId})

See here for details.

If you must use Underscore method:

var found = _.find(myCollection.models, function(item){
    return item.get('tranId') === tranId;
});

Because myCollection.models is an array, myCollection not.

I prefer the former one.

Solution 3

A collection does not mean exactly the same thing in Backbone (an object managing a list of models) and Underscore (a list of objects). What you should pass to _.find is myCollection.models

_.find(myCollection.models, function(model) {
    return model.get('tranId')===tranId;
});

As @Daniel Aranda explained, Backbone proxies Underscore methods on collections and you could write your example as

myCollection.find(function(model) {
    return model.get('tranId')===tranId;
});

Finally, if tranId is your model ID, you could set id as the idAttribute and simplify the whole thing by using get

var M=Backbone.Model.extend({
   idAttribute: "tranId"
});
var C=Backbone.Collection.extend({
    model:M
});

var myCollection=new C([
    {tranId:'not this one'} ,
    {tranId:'another'} ,
    {tranId:'1a2b3c'}
]);

myCollection.get(tranId);

And a Fiddle http://jsfiddle.net/rYPLU/

Share:
25,518
Pop-A-Stash
Author by

Pop-A-Stash

I'm a full-stack developer in Little Rock, Arkansas!

Updated on July 09, 2022

Comments

  • Pop-A-Stash
    Pop-A-Stash almost 2 years

    I'm trying to use the Underscore method 'find' on a collection but it is not giving me the results I expected:

    I have a base model with no defaults, and a default collection. The models in my collection have only two attributes: tranId(a guid as a string), and perform(a function to perform).

    I'm trying to find the item in the collection that matches the tranId that I pass it...

        var tranId = "1a2b3c";
    
        var found = _.find(myCollection, function(item){
            return item.tranId === tranId;
        });
    

    Found is always undefined, even though the debugger shows that my collection does, indeed have an item in it where tranId matches my variable. I am unable to set a breakpoint at the return statement to see what item.tranId equates to. I have also tried this...

        var found = _.find(myCollection, function(item){
            return item.get('tranId') === tranId;
        });
    

    But, same thing. 'found' is always undefined. What am I doing wrong here?

  • Pop-A-Stash
    Pop-A-Stash almost 12 years
    Thanks, that worked. Why doesn't the Underscore method work in the same way? It should also be noted that the tranId is a string, not a number. So, the typecasting is not needed.
  • Daniel Aranda
    Daniel Aranda almost 12 years
    @JoelCDoyle if you want to use underscore methods directly may be is better to use myCollection.models because it is raw Array of your models backbonejs.org/#Collection-models -- the typecast was in case that there was issues with the strict datatyping comparision. :D
  • Pop-A-Stash
    Pop-A-Stash over 9 years
    Very nice. I like the one line solution!
  • enricostn
    enricostn over 9 years
    Very useful, thanks! Just as an aside comment remember that the default idAttribute of a Backbone model is the id field, read the doc for more info