I'm using Iron router's onBeforeAction
method to check if user is logged on all routes except the register and login routes:
Router.onBeforeAction(function() {
if (!Meteor.user()) {
this.render('login');
}
else {
this.next();
}
}, {except: ['login', 'register']});
(FYI, the login process is made in the login template/js with this code)
This works well, except that when I'm logged the login template shows quickly before being replaced by the actual template.
When I checked what's happening, I found that Meteor.user()
is not ready before the Iron router is. As a consequence, the login page is showed like the user wasn't logged. And then (as Meteor.user()
is reactive), the route will run again when Meteor.user()
becomes ready, showing the correct template.
How can I make this little sample of code above working correctly? (Meaning: without showing the login template because of Meteor.user()
is not ready)
I've also found here on Stack Overflow that I can use the fast-render package, but I'm not willing to hack the render process. The onRun()
method doesn't fix this problem neither.
I've also read somewhere that I can use Router.configure
's waitOn
option but the only examples I've got are with subscriptions which I don't have yet (I'm prototyping with the insecure auto publish package).
I don't think this is the best solution, but the trick works fine:
Router.onBeforeAction(function() {
if (Meteor.user() !== undefined) {
if (!Meteor.user()) {
this.render('login');
}
else {
this.next();
}
}
else {
this.pause();
}
}, {except: ['login', 'register']});
This code sample works because Meteor.user()
is undefined before becoming ready and it is null if it's ready but there is no user logged in.
For my project, I even replaced this.pause()
by the loading screen:
Router.onBeforeAction(function() {
if (Meteor.user() !== undefined) {
if (!Meteor.user()) {
this.render('login');
}
else {
this.next();
}
}
else {
this.render('loading');
}
}, {except: ['login', 'register']});
I hope this will help somebody else.