When and how to use this.autorun()?


#1

Hello all,

I’ve been subscribing like so:

Template.Example.onCreated(function() {
  this.autorun(() => {
    this.subscribe('examples.all');
    this.subscribe('animals.dogs');
  });
});

I know this is correct as I followed the examples in the guide, but when else should I use autorun? For instance I have to check the FlowRouter route name sometimes and I put that in an autorun in onCreated. Is that correct? Should I use a separate autorun function for each task or use them same one for all tasks?

Thanks guys!


#2

You need to keep the following in mind:

An autorun establishes a reactive context which is re-executed whenever any reactive data it depends on changes. In addition, an autorun always runs once (the first time it is executed).

In your example, the first execution of the autorun subscribes to two publications. However, neither publication (nor anything else in that autorun) is a reactive dependency, so the autorun is never re-executed (there is no need). That means your example could be rewritten as:

Template.Example.onCreated(function() {
  this.subscribe('examples.all');
  this.subscribe('animals.dogs');
});

and it will work just as well.

If you have a conventional mapping of route name to template, then you should not need to check the FlowRouter route name. In any event, if you do need to check the name, then it probably should not be in a template autorun. The example in the docs uses a Tracker.autorun, which may be defined elsewhere (including globally).


#3

As @robfallows noted,

Therefore each autorun should be limited to a particular task. For example, perhaps you have an autorun that transforms some data when a checkbox is toggled, and another that retrieves a new page of data when the URL query parameters are updated (eg FlowRouter.getQueryParam). Since these are unrelated tasks, they need to be two separate autoruns; otherwise both tasks will run every time either scenario is triggered.


#4

Hi,

A useful example is when your home page needs data, but depending on your connection state :

Template.Example.onCreated(function() {
        this.autorun(function () {
            if(Meteor.user()) {
                Meteor.subscribe('someHomeDataOnlyForLoggedPeople');
            }
        });
});

Without the “this.autorun()”, everybody would make a subscription for nothing …
But when Meteor.user() will change, subscription will automatically be done :slight_smile:


#5

On Meteor 1.4.1

Template.Example.onCreated(function() {
        this.autorun(function () {
            console.log(new Date());
        });
});
Uncaught TypeError: this.autorun is not a function

#6

Are you sure your code didn’t look more like this:

Template.Example.onCreated(() => {
        this.autorun(function () {
            console.log(new Date());
        });
});

Using ES2015 “fat arrow” syntax in the onCreated will result in a _this.autorun is not a function error.

However, you can (and probably should) use fat arrow syntax on the autorun itself:

Template.Example.onCreated(function () {
        this.autorun(() => {
            console.log(new Date());
        });
});

#7

Thanks you so much :smile: