jmorrell / backbone.obscura

A read-only proxy of a Backbone.Collection that can be filtered, sorted, and paginated.
http://jmorrell.github.io/backbone.obscura/
MIT License
107 stars 19 forks source link

filtering nested collection #20

Closed massimopalmieri closed 10 years ago

massimopalmieri commented 10 years ago

I have a collection of models that looks like this:

[
    {
        "id": 1,
        "name": "mike",
        "pets": [
            { "id": 1, "type": "dog" },
            { "id": 2, "type": "cat" }
        ]
    },
    {
        "id": 2,
        "name": "john",
        "pets": [
            { "id": 1, "type": "dog" }
        ]
    }
]

is it possible with obscura to filter the users that have, for example, a cat?

jmorrell commented 10 years ago

Certainly! You can't use the shortcut syntax, but since you can filter with an arbitrary function as the predicate the following should work:

var coll = new Backbone.Collection(/* the data above */);
var proxy = new Backbone.Obscura(coll);

proxy.filterBy('cat-owners', function(model) {
  return _.some(model.get('pets'), function(obj) {
    return obj.type === 'cat';
  });
});

If you're supporting only ES5+ (e.g. IE 9+) you could use [Array#some] instead of the underscore method.

proxy.filterBy('cat-owners', function(model) {
  return model.get('pets').some(function(obj) {
    return obj.type === 'cat';
  });
});
massimopalmieri commented 10 years ago

thanks @jmorrell, I already tried that solution but it wasn't working, and I just realized that it's because, for some reasons, I was trying to convert the array of pets to a backbone collection:

var User = Backbone.Model.extend({
    defaults: {
        name: 'empty'
    },

    initialize: function() {
        this.set('pets', new Backbone.Collection(this.get('pets')));
    }
});