Filtering a collection in the template


#1

Hoping someone can help, I’m stuck on how to filter a collection for display based on user selections.

For example:

Say you have a list of recipes and they are grouped by ‘meat’ or ‘veg’. In the template, there is buttons for ‘Meat’ and ‘Veg’ and below the buttons is a drop-down with a list of recipes based on which button has been selected.

How do I set that up? I’m a bit lost with adding the interaction on the page as opposed to publishing/subscribing to the data.

Thanks in advance


#2

I think you should subscribe the client to complete collection.

Then, keep track of which item falls under which group (may be use data attribute).

Now, when user clicks ‘meat’, store that in Session, and hide those with ‘veg’. And do vice versa.

Having told you to use Session, I’ve seen people recommending ReactiveDict approach. But I’ve never used it.


#3

Personally for something like this I would say to use your router for this… Creating a route definition as something like /recipes/:group would be ideal. Then when you navigate to /recipies/meat you subscribe to only the necessary data (setting up pagination or infinite scroll if needed) and you render your page with only the group specified.

Router.route("recipes.group", {
    path:'/recipes/:group',
    template:'recipeSearch',
    data: function() {
        return Recipes.find({group:this.params.group});
    },
    subscriptions: function() {
        return Meteor.subscribe('recipesByGroup', this.params.group);
    }
});

Please don’t subscribe to every recipe record you have… First this well be taxing on your server and second it will be slow to load on the client… It will work ok if you only have about 100 records or so, but for an optimal response and render time, I wouldn’t recommend subscribing/rendering more than about 30 at a time. That being said you’ll likely want to paginate. Storing the current page in the query of the url is a very good place and if you’re using Iron Router it will provide you with a reactive variable to which you can respond to the changes of.


#4

I would agree with you however I probably need to elaborate on my context. The recipe selection is part of a larger form so I’m interested in being able to filter whilst already having delivered the template.
Totally agree on not subscribing to every record, the available recipes are already paired down on subscription.


#5

In which case I would say that storing the group in the query of the url is a good option for filtering that as well, that way if the user navigates away and then back the state of the form is preserved and they won’t have to redo the form… You could accomplish it through reactive vars on the template instance but I think query of the url is the cleanest solution.


#6

I think this is the way to go.


#7

Or set session variable and change subscription in Deps.autorun.

https://manual.meteor.com/#deps


#8

It’s called Tracker now :wink:

I would also use Tracker.autorun here but use use a ReactiveVar instead of Session.


#9

Yep, I just stumbled on ReactiveVar :smile: and have it working although I’m not using Tracker.autorun and will look into that.

Thanks for the replies all!