Race condition in rendering


#1

I have a template rendered in the HTML file with:

{{> header}}

This template renders a Materialize CSS sidebar:

{{#if currentUser}}
            <a href="#" data-activates="slide-out" class="expand-navigation left"><i class="mdi-navigation-menu"></ii></a>
            <ul id="slide-out" class="side-nav">
              {{#each modules}}
                {{> module}}
              {{/each}}
            </ul>
 {{/if}}

<template name="module">
    <li><a href="#">{{name}}</a></li>
</template>

I have tried the following places to init the plugin:

  • Template.header.onRendered(function () {});
  • Tracker.autorun(function(){ if(Meteor.userId()){}});
  • Template.header.rendered = function () {}
  • Template.header.rendered = function () { this.autorun(_.bind(function() { Tracker.afterFlush(function(){});}, this));};

The problem seems to be related to the if statement. If I remove the “{{#if currentUser}}”, it works fine. How do I catch the event that the user is logged in and the template is done rendering?

Sometimes (very seldom) it works. So is that a race condition? How can I influence it?

Edit 1:

If I call the init code on Template.module.onRendered it works, but is executed x times. There must be a better solution…


#2

@ibiasso,

The plugin must initiate after something renders, right? So why won’t you clear this logic a little bit, like this:

{{#if currentUser}}
  {{> userNav}}
{{/if}}

In this way you can call your plugin after userNav renders, and it will only render if you are logged in. It is a good thing to treat little parts of our app like components, even if it seems like you are breaking a lot of things down.

What do you think?


#3

@moretti: Good approach!

Created a template:

<template name="sidebar">
    <ul id="slide-out" class="side-nav">
        <li><a href="#">Dashboard</a></li>
        <li><a href="#">Orgas</a></li>
        <li><a href="#">Projects</a></li>
        <li><a href="#">Tickets</a></li>
        <li><a href="#">Logout</a></li>
    </ul>
</template>

Included the template:

{{> sidebar}}

Code for sidebar init:

Template.sidebar.onRendered(function(){

    $('.expand-navigation').sideNav({ closeOnClick: true });
});

Works fine :smile:


#4

I’m glad you liked it (: