In the previous videos, we saw how to track a subscription’s ready state at the template level.

In this episode, we’ll talk a little more about how to manage template state using Meteor’s ReactiveDict feature.

Template State

React explicitly distinguishes between a component’s state and props. The props are the properties passed to a component (such as the title and body in a comment-displaying widget), and they generally don’t change.

The state on the other hand is often internal to the component (such as the ready state mentioned before), and does change.

Meteor’s Template.instance().subscriptionsReady() method is a built-in reactive state variable, but we can also make our own.

ReactiveDict

In the onCreated callback, we initialize a new ReactiveDict. Although not documented, this feature works exactly like creating your own custom Session:

Template.myTemplate.onCreated(function () {

  var instance = this;

  instance.state = new ReactiveDict();

  this.state.setDefault({
    foo: "bar"
  });

  Meteor.call('getFooValue', function (error, result) {
    instance.state.set('foo', result);
  });
});

In this example, we’re initializing foo then calling the getFooValue method (which could query the server, an external API, or do any number of things) to retrieve its current value.

Since ReactiveDict is a reactive data store, the value of foo will update reactively once the method’s callback runs.

The Instance Helper

Now comes the clever part. We could create a foo template helper that outputs the value of our ReactiveDict variable:

Template.myTemplate.helpers({
  foo: function () {
    return Template.instance().state.get("foo");
  }
})

But that would get a bit long if we had more than 1 or 2 values in our template state. So instead, we’ll create a global Spacebars helpers that simply gives us access to the current template instance:

Template.registerHelper('instance', function () {
  return Template.instance();
});

And this means we’ll now be able to access our state directly from our templates, without the need for an extra helper:

<template name="myTemplate">
  <div>
    Foo is: {{instance.state.get "foo"}}
  </div>
</template>