Search code examples
javascriptbackbone.jsunderscore.jsbackgrid

Create object from Backbone collection that maps model values to one another


We are using Backgrid which allows you to define grid columns with an array of Javascript objects which it converts to a collection. We are trying to take advantage of this to have configurable validation on a column by column basis, so we might have the following where we've added a "validator" function to a couple of the columns:

[
    {
        label: "Delete",
        name: "delete",
        cell: "boolean"
    },
    {
        label: "Alias",
        name: "alias",
        cell: "string",
        sortType: "toggle",
        validator: function (value) {
            return true;
        }
    },
    {
        label: "Assigned Server",
        name: "assignedServer",
        cell: "string",
        sortType: "toggle",
        validator: function (value) {
            return new Error("Cannot Assign Server")
        }
    }
]

We are listening to edits to the grid in the following prescribed manner and for the purposes of this question we can ignore the model argument to the function but concentrate on the column (delete, alias or assignedServer from above) which is itself a model in a collection. So far I have a snippet of code leveraging underscore.js's _.filter that returns the validatableColumns but I want to take this further and end up with an object of the format {name: validator, etc...}. Bearing in mind my specific use case, what is a succinct way to create an object from a Backbone collection that maps model values to one another?

certificateGrid.listenTo(certificateCollection, "backgrid:edited", function (model, column) {                    
    var validatableColumns = _.filter(column.collection.models, function (c) {
        return c.get('validator');
    });

    //etc.

Solution

  • Using _.reduce seems to do the trick:

    var validatorFns = _.reduce(column.collection.models, function (fns, model) {
        var validator = model.get('validator');
        if (model.get('validator')) {
            fns[model.get('name')] = validator;
        }
        return fns;
    }, {});