Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly stopping an autorun() function when template is destroyed

Tags:

meteor

I have a template that contains a chart, rendered using MorrisJS. The chart should update when the currentData session variable is changed, so I have made it a reactive data source with:

Template.chart.rendered = function() {

    var template = this;

    Deps.autorun(function(c) {

        // Stop if the template is removed from the dom
        // Q: Is this really right?
        if(template.__component__.dom.parentNode() === null) {
            c.stop();
            return;
        }

        var results = Session.get('currentData');

        // ... render a chart with `results` as the data

        Morris.Bar({element: template.$(".chart-container"), data: results, ...});

    });

};

Notice how I do a fairly horrid check for when to stop the autorun above. This was necessary because without this, when I navigate away from the page using the template (I'm using iron-router) to another page and back, I get warnings in the log like "Can't select in removed DomRange". I'm pretty sure this is happening because the template instance is removed, but the autorun is still running.

I feel like I'm doing something wrong here, though. Is there (a) a better place to put the autorun so that it doesn't have this problem or (b) a better way to stop the computation when the template instance is removed from the DOM?

I tried to find a way to do it with created and destroyed handlers, but I couldn't figure out how.

like image 693
optilude Avatar asked Mar 19 '23 06:03

optilude


1 Answers

Tracker.autorun returns a handle that you can store as a template instance property, then call its stop method in the onDestroyed lifecycle event.

Template.chart.onRendered(function(){
  this.computation = Tracker.autorun(function(){...});
});

Template.chart.onDestroyed(function(){
  this.computation.stop();
});

EDIT 29-09-2014

In newer versions of Meteor (0.9 onward), there is a new autorun function available on template instances which provide simpler code to achieve the same result : no need to store and stop the computation manually, this is taken care of by the framework.

Template.chart.onRendered(function(){
  this.autorun(function(){...});
});
like image 63
saimeunt Avatar answered Apr 25 '23 10:04

saimeunt