How is pub/sub name linked to a collection?

I’m having trouble understanding how this works:

Template.homePage.onCreated ->
  this.subscribe 'coolThings', 3

Template.homePage.helpers
  things: -> Things.find()

If I’m subscribing to something called coolThings which is totally random, how does the Things.find() know to limit itself to the subscription??

Publications are declared on the server. They determine what gets sent to subscribing clients. The client can then subscribe to the publication. Whatever gets returned by that publication is what populates the MiniMongo DB on the client side.

Maybe Things is a collection with 100 documents, but only publishes 10. When the client subscribes to that publication and calls Things.find() only those 10 documents will get returned from the client’s MiniMongo instance. As far as the client knows, there are only 10 documents in Things.

In your example code, Things.find() will return everything the server saw fit to publish to the client, perhaps based on a parameter or the subscribers userId, commonly.

This, of course, assumes you’ve removed the autopublish package which publishes everything to everyone for the purpose of easier early development.

1 Like

That’s the thing, though. In my code example, Things.find() only returns 3 items because of this code:

this.subscribe 'coolThings', 3  # limit to 3 items

My question is, how does the Things collection know to limit its returned results? coolThings is just some random string, I could’ve called it “blahblahstuff.” How does Meteor know to link up Things with that subscription?

Because the publication is registered on the server:

//On the server
Meteor.publish('coolThings', function(param){
    // Some MongoDB query using param
    // Param is whatever you pass when you subscribe
    // on the client, in your example: 3
    // So you might use it to limit what the subscription returns
});

The client can now subscribe to a subscription called coolThings as it has been registered on the server. The server then determines what to return to the client. It is not a random string. If you just put a random string nothing will happen because the server probably hasn’t registered a publication named that random string.

Server publications do nothing without client subscriptions to those publications.

When you call Things.find() on the client, it is not directly communicating with the DB, it’s using a MiniMongo instance that replicates the DB, but is only populated with whatever documents the subscriptions return.

So the server determines what to send to the client, and as far as the client is concerned, that’s all that exists.

I think reading the documentation would be helpful: http://docs.meteor.com/#/basic/pubsub

I don’t think it does limit itself to the subscription. On the client, Things.find() will find all the things. It’s just that client has only cool Things because that’s all the server sent.

If you manually write an uncool thing to the client collection (bypassing the api and going straight to the mongo guts), it’ll show up for that query.

OH, got it! So if the publication returns Things.find({}, {limit: 3}), and then in the Template I have a helper that returns Things.find(), that call is operating on a subset of Things (3 items) returned by the publication, rather than the entire Things collection, right?

Yeah, sounds like you got it. Things.find() on the client will return everything in the client Things collection (which is a MiniMongo instance that lives in client memory). Meteor does it this way so you can use the same DB API on both the client and server, but still maintain data security and access through pubs and subs.

I think what might have been confusing in your original example is you were only looking at client code, and it’s not clear what’s happening without the server code as well (the publication).

That’s the idea. Probably best to think of publication as generating a cursor (which client subscribes to), not returning a set also. For one thing, when you do fancy shit with cursors, you don’t actually need to return them, just cause them to be created in the body of the publication function (yeah, I thought it was weird too).

Right. Ok, so with this example:

http://meteorpad.com/pad/K9ZYi9QZv23xZ9dfF/pubsub

The Things collection has three items, and even though the helper is returning Things.find(), only two items are returned because the publication the template is subscribed to is limiting the record set to two items. Just making sure I understand this.

I didn’t actually look (got stuff to do), but you have the basic idea. Play around with things to confirm/refute your model of how it works.

Unfortunately meteorpad doesn’t work over my corporate network but based on your description sounds like you understand it.