Template.subscriptionsReady always true?

I have the following template code to subscribe to two publications:

Template.chatHome.onCreated(function() {
  console.log(this.subscriptionsReady());
  Tracker.autorun(function() {
    Meteor.subscribe("messages");
    Meteor.subscribe("userStatus");
  });
  console.log(this.subscriptionsReady());
});

Template.chatHome.onRendered(function() {
  Tracker.afterFlush(function() {
    scrollToBottom();
  });
});

Then I have a layout template:

<template name="layout">
  {{> nav}}

  {{#if Template.subscriptionsReady}}
    {{>yield}}
  {{else}}
    {{>loading}}
  {{/if}}

  {{>footer}}
</template>

I want to “waitOn” the subscriptions before yielding the chatHome template or any other template passed to yield. I’m trying to switch to the pattern of subscribing at the template level. It seems as the Template.subscriptionsReady is always true. It loads the chatHome template and the data starts populating. Now my scrollToBottom() function has already fired and won’t work properly since all the data hasn’t been loaded yet.

I was using pecl:loading in combination with the waitOn iron router hook, but I no longer want to do subscriptions on the router so I can eventually move to flow router.

@nbrady there’s no point of putting Meteor.subscribe("messages") or Meteor.subscribe("userStatus") in autorun, it serves nothing in this case, there are no reactive arguments that would make the subscription to reload.

Also, you do Meteor.subscribe() which doesn’t trigger this.subscriptionReady at all. You need to use this.subscribe.

I thought that I may have needed to, to get the afterFlush functionality to work correctly.

Use this.subscribe("messages"); instead of Meteor.subscribe("messages");

1 Like

Yeah that totally did it. Now the problem is having my scrollToBottom() function go off after the data has been flushed.

Template.chatHome.onCreated(function() {
  this.subscribe("messages");
  this.subscribe("userStatus");
});

Template.chatHome.onRendered(function() {
  this.afterFlush(function() {
    scrollToBottom();
  });
});

Try calling Template.instance().subscriptionsReady()

There is a complementary function Template.instance().subscriptionsReady() which returns true when all of the subscriptions called with this.subscribe are ready.

I don’t see how this would help if it doesn’t take a callback for when it is ready?

At this point, the subscriptions work fine and I’ve got the loading template showing until the data is loaded. But it seems that my scrollToBottom() function is firing before all the data has flushed.

You can try using this inside the onCreated function?

this.autorun(function() {
    if (Template.instance().subscriptionsReady()) {
        console.log("Subscription is ready");
    }
});

This ended up working for me, just passing a callback to the subscribe method.

Template.chatHome.onCreated(function() {
  this.subscribe("messages", function() {
    Tracker.afterFlush(function() {
      scrollToBottom();
    })
  });
  this.subscribe("userStatus");
});

Thanks so much for the help!

Awesome! Glad it worked out.