Probably easy publish-subscribe question:


#1

easy publish subscribe question:

in the example below how do I actually access data from posts-current-user
in a client helper??

// server
Meteor.publish('posts-current-user', function publishFunction() {
  return BlogPosts.find({author: this.userId}, {sort: {date: -1}, limit: 10});
  // this.userId is provided by Meteor - http://docs.meteor.com/#publish_userId
}
Meteor.publish('posts-by-user', function publishFunction(who) {
  return BlogPosts.find({authorId: who._id}, {sort: {date: -1}, limit: 10});
}

// client
Meteor.subscribe('posts-current-user');
Meteor.subscribe('posts-by-user', someUser);

#2

I don’t think your doing it right, you would need to have two different collections defined.
You’ve used BlogPosts for both. The more recent subscription will likely overwrite the older one (not certain if that is how it works). You’ve got two subscriptions to the same collection.

I’ve never done this myself, but I think what you want to do is define two BlogPosts objects.

BlogPostsUser = Mongo.Collection('whateveryoucalledit');
BlogPostsCurrentUser = Mongo.Collection('whateveryoucalledit');

Then have two different subscription and publish calls…


#3

Hi Yes I was confused but I got it from here:

Any thoughts?


#4

Yeah sorry out of my league here!

I haven’t ever published the same collection twice like that before.
Not sure how that is supposed to work.


#5

You cannot list a specific subscription, rather you will have to rewrite the same query in your helper, i:e

//helper
'posts': function () {
    return BlogPosts.find({author: Meteor.userId()}, {sort: {date: -1}, limit: 10}).fetch();
}

Note: the user of Meteor.userId() and also the fetch() to convert the cursor to an array.

What the publish does is, give you a superset of rows you’ll need on the client.
Then on the client, you are querying minimongo to retrieve and format the data for presentation in your templates.

EDIT:
On the server, you want to return a cursor because this is reactive and your cilent helper will be kicked off each time this cursor changes. But on the client a cursor is not a list, so you must resolve it into an array via fetch before you can use it.


#6

You can have more than one subscription on the same collection, but need to know that it will be merged (look up merge box) on the client. In order to tease apart the data from your two subscriptions you need to use a query in your helper

if(Meteor.isServer){
 Meteor.publish('a-collection', function(){
  return Collection.find({key: 'a'});
 });
 Meteor.publish('b-collection', function(){
  return Collection.find({key: 'b'});
 });
}

if(Meteor.isClient)
{
 Meteor.subscribe('a-collection');
 Meteor.subscribe('b-collection');

 Template.collection.helpers({
  collection: function(key) {
   return Collection.find({key: key});
  }
 });
}

#7

Maybe I don’t understand what you mean, but generally speaking you should avoid converting a cursor to an array when returning it from a helper, as Blaze (the rendering package) performs better with a cursor. See here.


#8

@markpdev steve is right, don’t resolve your result via fetch, I got the wrong impression somewhere along the line for some other problem. In fact, I also just return cursors in my helper! Thanks @Steve for picking it up.


#9

Hi guys,

I just stumbled upon the same newbie-question.

The “best-practice conclusion” for me (as a newbie) is:
Just make one publish and one subscription per Collection
and just lowercase name it with the Collection name.

Everything else (have 2 publications of the same collection) is going to make the code less readable
and harder to debug.

Am I right? Or is there a use-case where it makes sense to have 2 publishs of the same Collection?