FlowRouter and Subscription management, understanding the examples


#1

I am migrating to FlowRouter from IronRouter and trying to understand subscription management. Both Kadira’s docs and Forum answers show subscription management through snippets like the following, where an onCreated handler uses autorun to reactively subscribe to a single post, and then a Template handler does a findOne to get it:

Posts = new Mongo.Collection('posts');

Template.postContent.onCreated(function() {
  var template = this;
  Tracker.autorun(function() {
    template.subscribe('singlePost', FlowRouter.getParam('_id'));
  });
})

Template.postContent.helpers({
  postData: function() {
    var post = Posts.findOne({_id: FlowRouter.getParam('_id')});
    return post;
  }
})

Could someone clarify for me how the template.subscribe in the autorun affects the content of the subscription bound o the Posts variable in the postData helper? It seems like there are two independent subscriptions, one named ‘posts’ and another named ‘singlePost’, and I don’t understand how they are connected. I believe this code works, I just don’t understand why. Thanks for your help.


#2

Posts is just the definition of the collection, no subscription yet (unless you have the package autopublish). Once the template postContent gets created, it subscribes to the a single post via the slug in the URL.

I usually use the autorun of the template

Template.postContent.onCreated(function() {
  var template = this;
  template.autorun(function() {
    template.subscribe('singlePost', FlowRouter.getParam('_id'));
  });
})

In the HTML portion of the template you can then use

<template name="postContent">
 {{#if Template.subscriptionsReady}}
  {{! show post}}
 {{else}}
   Loading
 {{/if}
</template>

#3

Thanks for the clarification. For anyone else who might be confused like I was, it’s important to see the actual publication code on the server side:

Meteor.publish('singlePost', function(id) {
  check(id, String);
  // Make a delay manually to show the loading state
  Meteor._sleepForMs(1000);
  return Posts.find({_id: id});
});

The sequence of events is like this:

  1. A collection Posts is created with name ‘posts’.
  2. A publication ‘singlePost’ is created on the server side. Because it returns a cursor to the Posts collection, Meteor knows that this publication should update the Posts collection on the client side. (The publication does not need to refer to the name of the collection (‘posts’), the return value is sufficient to make the binding occur.)
  3. The subscription on the client side refers to the name of the server-side publication (‘singlePost’), which enables Meteor to update the Posts collection on the client side according to the definition of the subscription.

So simple.

I assume that the var template = this; is required even in ES6.