2

I have two different subscriptions in my app:

 Meteor.subscribe('collection');

and

 Meteor.subscribe('filtered-collection',param1,param2);

I want to supply the data to different templates through different template helpers, say allResults and filteredResults respectively.

Since $geoWithin doesn't work at the client side and I need to use it for filtering, I cannot just filter the first subscription by

filteredResults = Collection.find(selector);` 

Therefore, I need a separate subscription for it.

So, the question is: how to find the result set from respective subscription and pass it through a helper?

pneumatics
  • 2,836
  • 1
  • 27
  • 27
Tabrez Ahmed
  • 2,830
  • 6
  • 31
  • 48
  • 2
    This gets asked a lot. Start with [this question](https://stackoverflow.com/questions/27748100/in-meteor-how-can-i-query-only-the-records-of-a-given-subscription) and read through the duplicate suggestions. I don't know that there is a canonical, straightforward answer to this question because it's somewhat at odds with how meteor works. – David Weldon Oct 12 '15 at 19:54
  • @DavidWeldon, thanks for the lead ..... Can you plz tell me why it is at odds with how meteor works? – Tabrez Ahmed Oct 12 '15 at 20:14
  • I mean, Isn't it a necessity actually .... – Tabrez Ahmed Oct 12 '15 at 20:18
  • 1
    To understand that you may want to read a bit about DDP and what it does. In essence it synchronizes collections. When you subscribe to a filtered collection it just means that only filtered elements get synchronized, but it is still the same collection. So when you than remove the filter by adding another subscription, you lose the filtering. This is why you need two collections. – Christian Fritz Oct 12 '15 at 20:33
  • 1
    This is a really good question because the server-side query is just not available client-side. The workarounds seem really clunky. – Michel Floyd Oct 13 '15 at 00:53

1 Answers1

0

I finally solved the problem. I don't think the solution is ideal though.

At Server:

Collection = new Meteor.Collection('collection');

Meteor.publish('collection',function(){
  return Collection.find();
});

Meteor.publish('filteredCollection',function(loc, radius){
  var selector = {};
  if (radius === undefined)
    radius = 100;
  if (loc !== undefined && !(isNaN(loc[0]) || isNaN(loc[1]))) {
    selector.loc = {
      $geoWithin: {
        $centerSphere: [loc, radius / 6371]
      }
    };
  }


  var sub = this,
      handle = null;

  var handle = Collection.find(selector).observeChanges({
    added: function(id, fields) {
        sub.added("filteredCollection", id, fields);            
    },
    changed: function(id, fields) {
        sub.changed("filteredCollection", id, fields);            
    },
    removed: function(id) {
        sub.removed("filteredCollection", id);
    }
  });

  sub.ready();

  this.onStop(function() {
      handle.stop();
  });

});

At client:

Collection = new Meteor.Collection('collection');
FilteredCollection = new Meteor.Collection('filteredCollection');


Meteor.subscribe('collection');
Meteor.subscribe('filteredCollection',loc,radius);


Template.collection.helpers({
  collection: function(){
    return Collection.find();
  },
  filteredCollection: function(){
    return FilteredCollection.find();
  }
});

At the client, Collection and FilteredCollection are two different subsets of the same underlying collection at the server. But whether the two subsets are dependent on each other in terms of caching and persistence, is (I think) a different question altogether.

Tabrez Ahmed
  • 2,830
  • 6
  • 31
  • 48