Search code examples
javascriptfunctionbackbone.jsunderscore.js

using a model's function in _.map from within a collection


I use backbonejs and underscorejs. I have a Person model with a getFullName() function and a Persons collection with a getSummary() which should return all full names of the persons contained. My current implementation is:

var Person = Backbone.Model.extend({
    defaults: {
        name: '',
        surname: ''
    },
    getFullName: function() {
        return this.get('name') + ' ' + this.get('surname');
    }
});

var Persons = Backbone.Collection.extend({
    model: Person,
    getSummary: function() {
        return _.map(this.models, function(person) {
            return person.getFullName();
        }).join(', ');
    }
});

console.log(
    new Persons([
        {name: 'john', surname: 'smith'},
        {name: 'mary', surname: 'poppins'}
    ]).getSummary()
);

This works well and I get the following displayed in the console:

john smith, mary poppins

My problem is that I don't want to be so verbose in the getSummary() function. I'd like to simply be able to pass the model's function instead of having to create a function to call it. Maybe something like this:

getSummary: function() {
    return _.map(this.models, 'model.getFullName').join(', ');
}

Is this possible somehow?


Solution

  • Backbone proxies a lot of Underscore functions on collections and models, most notably the very nice _.invoke :

    invoke _.invoke(list, methodName, *arguments)
    Calls the method named by methodName on each value in the list. Any extra arguments passed to invoke will be forwarded on to the method invocation.

    You can simplify your method like this:

    getSummary: function() {
        return this.invoke('getFullName').join(', ');
    }
    

    And a Fiddle http://jsfiddle.net/nikoshr/pxpon64q/