Jeanluca Scaljeri
Jeanluca Scaljeri

Reputation: 29199

meteor.js: understanding publishing

I recently started with Meteor, and one thing I still don't understand (not completely at least) is the publishing mechanism. For example, consider the following code (I have disabled autopublish btw):

file: client/lib.js

var lists = new Meteor.Collection('List');
Meteor.subscribe("Categories");

Template.categories.lists = function () {
     return lists.find({}, {sort: {Category: 1}});
};

file: server/lib.js:

var lists = new Meteor.Collection('List');
Meteor.publish("Categories", function() {
   return lists.find({},{fields:{Category:1}});
});

2 questions:

An other questions I have is about the following code:

file: client/lib.js:

Meteor.autosubscribe(function() {
    Meteor.subscribe("listdetails", Session.get('current_list'));
});

file: server/lib.js:

Meteor.publish("listdetails", function(category_id){
   return lists.find({_id:category_id});
});

I assume that when listdetails gets published, the new list is pushed into current_list from Session. I don't understand why you cannot just simply do

Meteor.subscribe("listdetails", Session.get('current_list'));

Furthermore, I noticed that these days you should use the Deps (Dependency) Object. Can someone translate this example for me using Deps ?

Thanks!

Upvotes: 0

Views: 150

Answers (2)

Hubert OG
Hubert OG

Reputation: 19544

Should I define in every file the lists collection ?

No. In fact, you cannot define the same collection twice on the client, you'll get an error (probably on the server as well, I don't remember). What you want to do is to define it as a global variable. To do so, remove the var keyword when you define it. Variables defined with var are local to the file you define them, variables without it are global.

Notice also that the untold convention is to name collections with Capital letters, and subscription with small, so you may want to update your code to Lists and categories for better readability.

How does the Meteor.subscribe("Categories"); knows to update the lists variable?

You return cursor from that collection in the channel, and the cursor is passed to the respective collection on the client side. Notice here that it's not the variable name that matters, but rather the argument you pass when calling new Meteor.Collection.

Can someone translate...

The example you've posted is outdated. There no longer is a Meteor.autorun function, instead it's called Deps.autorun. That's all the translations you need in your case. You can read about the Deps and how they work in the documentation.

I don't understand why you cannot just simply do...

That would call the subscription once with the current value of your Session variable as an argument. If you want the subscription to rerun when the value changes, you need to call in in something that's called "reactive context" (see the Deps documentation for details). The default way to achieve this is to put your call inside Deps.autorun method. When you do so, the subscription will be updated each time the value in your Session variable changes – which is the main reason why you would use Session.

Upvotes: 2

Peppe L-G
Peppe L-G

Reputation: 8360

should I define in every file the lists collection ?

No, evaluating new Meteor.Collection('<name>') many times (with the same <name>) gives you the error There is already a collection named '<name>'. Only evaluate it once and store it in a global variable.

how does the Meteor.subscribe("Categories"); knows to update the lists variable ?

It just does know how. As an ordinary programmer using Meteor, you don't need to know how. At least I won't tell you how, but it's no secret: the entire framework is available on github, just check the code there if you're interested.

An other questions I have is about the following code:

You could just use Meteor.subscribe("listdetails", Session.get('current_list'));, but then the subscription would just use the value Session.get('current_list') got at the moment. By using Deps.autorun(function() { Meteor.subscribe("listdetails", Session.get('current_list')); }); instead, the subscription is recreated each time Session.get('current_list') changes (when Session.set('current_list', <new-value>) is evaluated).

It is Deps.autorun you should use, Meteor.autorun and Meteor.autosubscribe are retired.

Upvotes: 2

Related Questions