I was reading through The Meteor Manual when I came across this tidbit which thoroughly surprised me:
Using Collection.find() doesn’t set up any reactive dependencies.
I didn’t think I had been asleep at the wheel, but I wouldn’t be surprised if I misunderstood something. So I jumped over to the official docs and took a closer look. I think the message is a bit muddled because of the opening line below, but sure enough it is at least indirectly implied that cursors alone will not setup reactive dependencies.
From: http://docs.meteor.com/#/full/find
Cursors are a reactive data source. On the client, the first time you retrieve a cursor’s documents with fetch, map, or forEach inside a reactive computation (eg, a template or autorun), Meteor will register a dependency on the underlying data."
“But wait!” I said, "don’t they return only cursor.find() in plenty of examples that are in theory reactive?
Some more sifting around in the docs shows this to be true:
<!-- in myapp.html -->
<template name="players">
{{#each topScorers}}
<div>{{name}}</div>
{{/each}}
</template>
// in myapp.js
Template.players.helpers({
topScorers: function () {
return Users.find({score: {$gt: 100}}, {sort: {score: -1}});
}
});
Even though this does work, how can it? A call to Users.find() does not setup any reactive dependencies, right? Or am I taking crazy pills!
My search for answers eventually lead me to the spacebars documentation which provides what I believe is the closest thing to answering my question(s).
So I am left with the educated guess that passing a cursor to the {{#each}} helper, or for that matter the {{#if}} or {{#with}}, leads eventually to the calling of .fetch(), .map(), or .forEach() on the cursor. This in turn establishes reactive dependencies.
If my assumption is correct then I guess this story is just a vote to make this more explicit in the documentation. Additionally maybe there is a nuanced differentiation between a “Reactive data source” which the documentation calls all cursors, and something that establishes reactive dependencies inside an autorun or template (or maybe not).
Also does passing a cursor vs. the results of fetch() to {{#each}} still provide the same benefit described here now that Blaze is used? In the latter case would the whole {{#each}} block be re-rendered if the data in the cursor changes?