Some code in onRendered function don't rerun on page reload!


#1
Template.humans.onRendered(function () {
this.$('#gender').selectize();
this.$('#origin').selectize();
this.$('#birth-date').datepicker({
	autoclose: true,
	todayHighlight: true,
	weekStart: 6,
	format: 'yyyy-mm-dd'
}); 

});

at first load things go fine, when reloading the page this initialisations don’t work!


#2

How do you reload the page?


#3

by refreshing the page for example


#4

You mean by hitting the browser refresh button? In that case onRendered should be called (if your template is displayed).


#5

Thanks Steve for your response, I know this is very old, but I still need the solution.

Actually, When hitting the ‘refresh button’ in the browser it do nothing, but if I navigate to another page and hit the “back button” on the browser things get messy and the code inside don’t re-run. and in this situation, after hitting back, if I tried even to refresh the page, the code also won’t re-run.

anybody know what is the best way to do this, I’ve to initialise some code every time the page renders?


#6

It will help you getting some answers if you posted a repro (preferable) or at least some code snippets and details of your project… i.e., are you using a router for page nav? which one? what causes your template to be created (your html and template insertion code)?

If not…


#7

Thanks @hluz,

I using Flowrouter and here is the route I want to get initialisations work with:

FlowRouter.route('/', {
  name: 'root',
  action() {
    Tracker.autorun(function() {
      if (Meteor.userId()) {
        BlazeLayout.render('layoutA', { nav: 'nav', main: 'feed' });
        Template.layoutA.onRendered(function() {
          $(document).foundation();
        });
      } else {
        BlazeLayout.render('layoutB', { nav: 'nav', main: 'landingPage' });
        Template.layoutB.onRendered(function() {
          $(document).foundation();
        });
      }
    });
  }
});

the problem is that now on browser reload or navigating out to any other route and hitting back button the initialisation doesn’t re-run

and here is the affected layout template:

<template name="layoutA">
  <div id="page">
    {{> Template.dynamic template=nav}}
    <div id="main" class="columns">
      {{> Template.dynamic template=main}}
    </div>
    {{> Template.dynamic template=footer}}
  </div>
</template> 

the interesting part is that the problem only happens within nav dynamic template section, I even tried to put the nav code inside main template section and it worked well!
I even tried to initialize for nav on its own, but didn’t solved it.

any help why this may be happening?


#8

This is where I would start: I would remove any sort of reactivity out of the route (tracker.autorun … ). And also the Template onRendered for the layout template(s). Leave only the BlazeLayout.render() - one only in each route.


#9

This didn’t solve it


#10

Is the nav template changing or are you expecting the same nav template to re-render just because you change routes? If the later, then that will not happen. onRendered will only execute once per template instance after is it added to the DOM.

I’m not really sure what exactly you are trying to resolve here… back to you original question:

Template.humans.onRendered(function () {
this.$(’#gender’).selectize();
this.$(’#origin’).selectize();
this.$(’#birth-date’).datepicker({
autoclose: true,
todayHighlight: true,
weekStart: 6,
format: ‘yyyy-mm-dd’
});
});

at first load things go fine, when reloading the page this initialisations don’t work!

Assuming that when you say “reloading the page” you mean change route, if the template instance is already attached to the DOM, them there will be no onRendered.

If you need to run the selectize code again because the data context for the dropdown has changed then you should warp those bit inside an autorun referencing the data context, not by trying to get onRendered to execute again.


#11

Thank you very much @hluz for your efforts, the selectize code was the first thing I faced the problem with, and solved it as you mentioned, but the problem now, as I mentioned later, in initializing things that don’t depend on data context, like zurb foundation ui framework, and the recommended place is inside onRendered as per their docs.


#12

In general, it is better to initialise these ui frameworks from within onRendered on the lower-level templates. If the template data context can change without triggering the onRendered code, then use a template instance autorun to wrap a reference to the data context and the initialisation code.