Confusion with Template.subscriptionsReady

i am trying to implement a spinner (sacha:spin) on a working template:

<template name="foo">
  {{#if Template.subscriptionsReady}}
    aaa
  {{else}}
    Loading...
    {{> spinner}}
  {{/if}}
</template>

Template.foo.onCreated(function() {
  Meteor.subscribe('foodata');
});

Meteor.publish('foodata', function() {
  return Foo.find();
});

once foodata is ready, i see “aaa” onscreen. now i do this:

Meteor.publish('foodata', function() {
  //return Foo.find();
});

… in hopes of seeing the spinner or “Loading…”. i see neither. when i inspect using the dev tools, i don’t see any sign of those elements. (i.e. it’s not simply that they are elsewhere). however, i totally see the spinner when i do either of these (and the publish is restored):

<template name="foo">
    {{> spinner}}
</template>

<template name="foo">
  {{#if Template.subscriptionsReady}}
    {{> spinner}}
  {{/if}}
</template>

so it seems there’s some kind of timing issue, or my lack of understanding, for what it means for templates to be ready. have i done this incorrectly?

Instead of Meteor.subscribe you have to use this.subscribe to put it into the template’s context

Template.foo.onCreated(function() {
  var self = this;
  self.subscribe('foodata');
});

ok thanks.

i have Meteor.subscribe() in all my templates. is it correct to change all of them, or are there reasons to use one over the other?

If you want to use Template.subscriptionsReady then you need to subscribe in the template. You can read up on this in the guide.

thanks for the link, this part in particular was useful to learn:

Technically, what happens when one of these reactive sources changes is the following:

  1. The reactive data source invalidates the autorun computation (marks it so that it re-runs in the next Tracker flush cycle).
  2. The subscription detects this, and given that anything is possible in next computation run, marks itself for destruction.
  3. The computation re-runs, with .subscribe() being re-called either with the same or different arguments.
  4. If the subscription is run with the same arguments then the “new” subscription discovers the old “marked for destruction” subscription that’s sitting around, with the same data already ready, and simply reuses that.
  5. If the subscription is run with different arguments, then a new subscription is created, which connects to the publication on the server.
  6. At the end of the flush cycle (i.e. after the computation is done re-running), the old subscription checks to see if it was re-used, and if not, sends a message to the server to tell the server to shut it down.

it sounds like, in templates, there’s no reason to ever user Meteor.subscribe(). i’ll proceed with that mind.