When displaying a list of documents, it can be clearer to write the subscription at the document level (vs at the list level), in case the template is reused somewhere else for instance. Is it less efficient or is Meteor handling things magically?
More precisely, I can put the document logic in the document template:
Template.itemsList.helpers({
items: function() {
return this.itemsIds.map(function(id) { return { _id: id }; });
},
});
<template name="itemsList">
{{#each items}}{{> item}}{{/each}}
</template>
Template.item.onCreated(function() {
this.subscribe('item', this.data._id);
});
<template name="item">
{{#if Template.subscriptionsReady}}
...
{{/if}}
</template>
or subscribe only once to those documents at the list level:
Template.itemsList.onCreated(function() {
this.subscribe('items', this.data.itemsIds);
});
Template.itemsList.helpers({
items: function() {
return Items.find({_id: {$in: this.itemsIds}});
},
});
<template name="itemsList">
{{#if Template.subscriptionsReady}}
{{#each items}}{{> item}}{{/each}}
{{/if}}
</template>
<template name="item">
...
</template>
It looks like the second approach it more efficient, since there is only one call to a subscription. If we were talking standard http requests here, there'd be no doubt. But since Meteor is socket based and handle a lot of things well under the hood, I was wondering it it was worth the trouble to move some logic away from the document to the list.
Generally it is better to call subscribe once. When you run subscribe with new params the publish method re-runs, then it makes call to db to fetch needed documents and sends it to client. It is generally better and more efficient to make only one call to db.
But this makes sense if you are sure you want to display all items and if there is not too many items in Items
collection.
If there is a big number of items (hundreds or more) it is better to do some kind of pagination to avoid downloading all documents to client.