title: How do I properly filter data with meteor publish/subscribe so I don't retrieve more data than the client wants to see?
body: <p>I have a meteor app where I want to let the user click buttons to switch between 2 different filtered views of the data, say "chart" records with a status of 10 or 11.  Some users of the app might never want to see status 10, while others might never want to see status 11.</p>
  
  <p>I'm trying to find a way through publish/ subscribe to work this out most efficiently... not pulling up records someone doesn't want to see, while also reducing network traffic.</p>
  
  <p>First idea was the following... a publish on the server with a parameter of the status:</p>
  
  <pre><code>  Meteor.publish("charts1", function (status) {
      console.log('someone subscribed to my publish of charts.. returning all charts now of status ' + status + " max 500 though");
      return Chart.find({"chartStatus": status}, {limit: 500, sort: {"demographics.lastName": 1}});
    });
  </code></pre>
  
  <p>then, on client, I have a template helper:</p>
  
  <pre><code>chartsOnClient: function () {
        return Chart.find({"chartStatus":Session.get('currentStatusFilter')}, {sort: {"demographics.lastName": 1}});
      }
  </code></pre>
  
  <p>and 2 buttons which, when clicked will set the session filter and subscribe at the same time:</p>
  
  <pre><code>Template.addChartForm.events = {
      'click #mybutton10': function () {
        console.log("subscribing to to status 10...");
        Session.set('currentStatusFilter', 10);
        Meteor.subscribe('charts1', 10);
      },
      'click #mybutton11': function () {
        console.log("subscribing to status 11...");
        Session.set('currentStatusFilter', 11);
        Meteor.subscribe('charts1', 11);
      },
  }
  </code></pre>
  
  <p>and, of course, a template that iterated over "chartsOnClient" to display the records.</p>
  
  <p>This worked... when I clicked button10, I got status 10 in my template, and clicking button11 gave me status 11 in my template...And, the added benefit was that if I never clicked button11, my local client only held the records of status 10, and vice versa, and clicking both buttons would fill up my local collection with the union of both sets.  </p>
  
  <p>The only issue I see with this method is that every click of the buttons results in the server message "someone subscribed to my publish of charts..."... indicating that the client is talking to the server and running the find method.</p>
  
  <p>I suspect this is not ideal... for, if I wanted, I could move the 2 "subscribe" calls <em>outside</em> of the click events, like this:</p>
  
  <pre><code>Meteor.subscribe('charts1', 10);
  Meteor.subscribe('charts1', 11);
  
  Template.addChartForm.events = {
      'click #mybutton10': function () {
        console.log("subscribing to to status 10...");
        Session.set('currentStatusFilter', 10);
      },
      'click #mybutton11': function () {
        console.log("subscribing to status 11...");
        Session.set('currentStatusFilter', 11);
      },
  }
  </code></pre>
  
  <p>and when I do this, I get the same end user experience, however, the server console only shows the "someone subscribed to my publish"... message once upon startup, instead of every time the buttons are clicked.</p>
  
  <p>The downside is that both sets of records are pulled up to the client for each user, even users that might never click on both buttons.  But the upside is that the subscribe method is not called each time they click to switch between views of the data...</p>
  
  <p>Is there something I'm not understanding here?  Which method is best? is there a better way to do this altogether?  I'm new to meteor and mongo.</p>
  
  <p>Thank you.</p>
  
  <p>Edit, based on @mattk , I am going to do the subscribes in the button clicks, but use an array in a session variable to prevent a second subscription if I've already subscribed with that particular filter:</p>
  
  <pre><code>'click #mybutton10': function () {
    Session.set('currentStatusFilter', 10);
    var filtersAppliedSoFar = Session.get('filtersAppliedSoFar');
    if (filtersAppliedSoFar.indexOf(10) == -1) {
      console.log("subscribing to to status 10...");
      filtersAppliedSoFar.push(10);
      Session.set('filtersAppliedSoFar', filtersAppliedSoFar);
      Meteor.subscribe('charts1', 10);
    }
  },
  'click #mybutton11': function () {
    Session.set('currentStatusFilter', 11);
    var filtersAppliedSoFar = Session.get('filtersAppliedSoFar');
    if (filtersAppliedSoFar.indexOf(11) == -1) {
      console.log("subscribing to status 11...");
      filtersAppliedSoFar.push(11);
      Session.set('filtersAppliedSoFar', filtersAppliedSoFar);
      Meteor.subscribe('charts1', 11);
    }
  },
  </code></pre>
  
  <p>This way, I don't pull up the data until the user clicks on the particular filter, but I also don't resubscribe if they click back and forth between the 2 filters, which is expected.</p>
  
  <p>EDIT AGAIN:  after asking this question <a href="https://stackoverflow.com/questions/29310306/how-do-you-securely-log-out-and-clear-all-subscriptions">How do you securely log out and clear all subscriptions?</a>  and getting directed toward Subscription Manager <a href="https://github.com/meteorhacks/subs-manager" rel="nofollow noreferrer">https://github.com/meteorhacks/subs-manager</a> I have discovered that Subscription manager achieves what I was looking for here:  I didn't want it to hit the server a second time if my client called .subscribe again.  Instead of using a session variable (filtersAppliedSoFar) to know if the client has already subscribed, the subs manager keeps track of this automatically...I just call .subscribe on the subscription manager object and it won't hit the server the second time.  .. then the added benefit is I can call .clear() when logging out and all subscriptions are stopped.</p>