1

I want to publish and subscribe subset of same collection based on different route. Here is what I have

In /server/publish.js

Meteor.publish("questions", function() {
  return Questions.find({});
});

Meteor.publish("questionSummaryByUser", function(userId) {
  var q = Questions.find({userId : userId});  
  return q;
});

In /client/main.js

Deps.autorun(function() {
  Meteor.subscribe("questions");
});
Deps.autorun(function () {
  Meteor.subscribe("questionSummaryByUser", Session.get("selectedUserId"));
});

I am using the router package (https://github.com/tmeasday/meteor-router). They way i want the app to work is when i go to "/questions" i want to list all the questions by all the users and when i visit "/users/:user_id/questions", I want to list questions only by specific user. For this I have setup the "/users/:user_id/questions" route to set the userid in "selectedUserId" session (which i am also using in "questionSummaryByUser" publish method.

However when i see the list of questions in "/users/:user_id/questions" I get all the questions irrespective of the user_id.

I read here that the collections are merged at client side, but still could not figure a solution for the above mentioned scenario.

Note that I just started with Meteor, so do not know in and outs of it.

Thanks in advance.

Community
  • 1
  • 1
ams
  • 15
  • 4

1 Answers1

2

The good practice is to filter the collection data in the place where you use it, not rely of the subset you get by subscribe. That way you can be sure that the data you get is the same you want to display, even when you add further subscriptions to the same collection. Imagine if later you'd like to display, for example, a sidebar with top 10 questions from all users. Then you'd have to fetch those as well, and if you have a place when you display all subscribed data, you'll get a mess of every function.

So, in the template where you want to display user's questions, do

Template.mine.questions = function() {
    return Questions.find({userId: Meteor.userId()});
};

Then you won't even need the separate questionSummaryByUser channel.

 


 

To filter data in the subscription, you have several options. Whichever you choose, keep in mind that subscription is not the place in which you choose the data to be displayed. This should always be filtered as above.

Option 1

Keep everything in a single parametrized channel.

Meteor.publish('questions', function(options) {
  if(options.filterByUser) {
    return Questions.find({userId: options.userId});
  } else {
    return Questions.find({});
  }
});

Option 2

Make all channel return data only when it's needed.

Meteor.publish('allQuestions', function(necessary) {
  if(!necessary) return [];
  return Questions.find({});
});

Meteor.publish('questionSummaryByUser', function(userId) {
  return Questions.find({userId : userId});  
}); 

Option 3

Manually turn off subcriptions in the client. This is probably an overkill in this case, it requires some unnecessary work.

var allQuestionsHandle = Meteor.subscribe('allQuestions');

...

allQuestionsHandle.stop();
Hubert OG
  • 19,314
  • 7
  • 45
  • 73
  • i understand we can filter out records in the template helper itself, however assume that I have 1000 questions (for all the users), so when i visit "/users/:user_id/questions" ideally i want to get only the questions of specific user down the wire rather then all the 1000 records. right now with the code that I have, i seem to get all the questions down the wire. – ams Jul 27 '13 at 04:16
  • also if i have pagination (e.g. 5 per page) applied in "/questions" page and then when i visit '/users/:user_id/questions", the questions list i get is only those 5 questions that i had in the "/questions" page. – ams Jul 27 '13 at 04:54