Samuel Goldenbaum
Samuel Goldenbaum

Reputation: 18909

Backbonejs - filtering collections within models

I have a collection of Vehicle Ranges. Each Range has an array of VehicleModels containing the models in that range. i.e.

Backbone Model and Collection:

App.Models.Range = Backbone.Models.extend({});
App.Collections.Ranges = Backbone.Collection.extend({
   model: Range
});

JSON:

[{
    "Name": "Range A",
    "VehicleModels": [
        {
            "Name": "1.2",
            "Fuel": "Petrol"
        },
        {
            "Name": "1.3",
            "Fuel": "Petrol"
        },
        {
            "Name": "1.6",
            "Fuel": "Petrol"
        }
    ]
},
{
    "Name": "Range B",
    "VehicleModels": [
        {
            "Name": "x1",
            "Fuel": "Diesel"
        },
        {
            "Name": "x2",
            "Fuel": "Diesel"
        },
        {
            "Name": "x3",
            "Fuel": "Diesel"
        }
    ]
}]

How can a filter the collection to return ranges than have VehicleModels with attributes that match a filter condition. i.e. return all ranges that have vehicle models with the Fuel attribute equal to 'Petrol'. Easy enough to filter the collection by model attributes like:

filterByFuel: function(fuel){
   return this.models.where({'Fuel': fuel});
}

or

filterByFuel: function(fuel){
   return this.models.filter(function(vehicle) {
                     return vehicle.get('Fuel') === fuel;
                });
}

But need to search the VehicleModel collection in each Range and return the Range if there is a match.

Tips greatly appreciated.

EDIT

I have the following which seems to work, but was curious if there was a better way. Underscores "contains" function seemed like the right thing, but could not get it to work:

 models = models.filter(function(range) {
                if (_.where(range.get('VehicleModels'), { 'Fuel': params.fuel }).length > 0)
                    return range;
            });

Upvotes: 0

Views: 1016

Answers (1)

neeebzz
neeebzz

Reputation: 11538

First of all Backbone doesn't treat nested objects as separate collections. They are just arrays.

So when you do :

this.model.get("VehicleModels")

You will only get an Array type object and not a Backbone.Collection.

To filter a plain array, you should use underscore's filter method.

_.filter( this.model.get("VehicleModels"), function(mod) { /* your condition */ } );

Upvotes: 1

Related Questions