adelphia
adelphia

Reputation: 187

Fetch a backbone collection with only the models with specified value

I have a dictionary of type {name: value}

A = {
  name: x,
  name: y,
  name: z
}

I want to fetch a collection (consisting of models having one of their attribute as 'name'), but to be optimal I want to fetch such that the value of the attribute 'name' exists in my dictionary.

Is there a way to do specific filtering like that?

Upvotes: 0

Views: 715

Answers (2)

Jeppe Stougaard
Jeppe Stougaard

Reputation: 422

If you're doing the filtering client-side, overriding the filter method is really NOT the way to go.
Now you no longer have it available, should you need it later. Also, modifying the collection itself from within the filter method is an undesirable sideeffect.

Instead you should be using the parse method, which will automatically be called when fetching the collection.

Now as I understand it, you want to limit the fetched set to models with names matching the keys in your dictionary.

If so, I would do the following:

parse: function(response, options) {
    // Do we want to filter the response?
    if (options.filterNames) {
        // Filter
        response = _.filter(response, function(obj) {
            // Check if this model name is one of the allowed names
            return _.contains(options.filterNames, obj.name);
        });
    }

    // Backbone will use the return value to create the collection
    return response;
}

And then call fetch using

someCollection.fetch({filterNames: _.keys(someDictionary)});

If you're certain, you will always be filtering the collection on fetch, you can omit passing the option and just use the dictionary within parse.

Alternatively you could create a fetchFiltered() method on the collection, which would then invoke the line above.

Upvotes: 4

adelphia
adelphia

Reputation: 187

After investigations and trials, here are the two ways this can be resolved: 1. Client side filtering after fetching the collection from the server. This is a less optimal method, especially when the collection is huge. In situations when you really want 5 models out of a 1000 model collection, it can be an overkill. But if the server side has no logic of accepting and using the filtering client side filtering should look something like:

Overload the collection filter code something like:

var filter = {
    filter: function() {
        var results = _.filter(this.models, function(model) {
            // Perform the check on this model, like compare it to your local dict
            if (checkPassed) {
                return true;
            }
            return false;
        });
        results = _.map(results, function(model) {
                                return model.toJSON();
                        });
        // Reset the existing collection to filtered models
        this.reset(results) ;
};
var ExtendedCollection = OriginalCollection.extend(filter);
  1. Pass a filter option in the fetch ajax call to the server, and the server should understand the filter and return the collection based off that.

Upvotes: 0

Related Questions