Last Updated: December 26, 2018
·
18.53K
· zimok

Return a Backbone collection when filtering a Collection

In order to filter a Backbone.Collection, you are maybe doing this:

Collection.filter(/* your filter condition */)

The problem is that the result you get is a simple javascript Array and not a Backbone.Collection instance.

There are some case when you'd like to be able to use convenient Collection methods to filtered values.

To achieve this, just wrap the returning object into an Underscore object:

var filtered = _(collection.filter(/* filter condition */));
/* calling a Backbone.Collection method */
console.log(filtered.size())

Not very elegant, but it does do the job.

3 Responses
Add your response

Your example does not wrap the results in a new Backbone Collection as your title says. Instead it wraps it in an Underscore object, that happens to have a .size() that acts the same as a Backbone Collection's .size() would. To actually wrap the results in a backbone collection you'll need something like this:

var filtered = new Backbone.Collection(collection.filter(function(model) {
    return model.get('name').substr(0, 1) === 'b';
}));

For a more generic way you could add this function to your base object, to demonstrate with working code I'll patch it into Backbone.Collection.

Backbone.Collection.prototype.filteredCollection = function(iterator) {
    // If you're using a collection that extends Backbone.Collection
    // the constructor will give you the same type of object back.
    return new this.constructor(this.filter(iterator));
}
over 1 year ago ·

Thanks guys, helped me a lot!

over 1 year ago ·

The correct way to do this is:
this.collection = this.collection.reset(this.collection.filter(...));

This will create a collection that is the same type as the original.

over 1 year ago ·