Search code examples
javascriptmeteorurl-routing

Meteor LogginIn() shows loading when not needed


i am following Discover meteor book and in one of the chapter author taught me to use Meteor.logginIn() method.

The goal is Simple, there is a submit page for new post and if there are no users logged in, it should display access denied template, else it should display post submit template. But if the user is loggin in or in wait state it should display loading template. I followed the tutorial and did what was told, the code looks exactly the same as the book. But, when user is logged in it rightfully display the submit page and when user is logged out it should display the access denied page but instead shows the loading template, while showing loading template if i log in, then it also display the submit page. The only trouble is while it should display the access denied, it is showing loading template.

Here is the routing code

Router.route('/submit', {name: 'postSubmit'});

var requireLogin = function(){
    if(!Meteor.user()){
        if(Meteor.logginIn()){
            this.render(this.loadingTemplate);
        }else{
            this.render('accessDenied');
        }
    }else {
        this.next();
    }
}
Router.onBeforeAction('dataNotFound', {only:'postPage'});
Router.onBeforeAction(requireLogin, {only:'postSubmit'});

Solution

  • Eh, that code could use a little help. Like for this instance, we are going to separate concerns and call them in different hooks

    First, keep in mind that every time you call onBeforeAction it adds that function to an array of and called sequentially. Although it's always a good practice not to actually depend on the sequential order, but it's great to keep in mind.

    var userLoggingIn = function() {
       if(Meteor.loggingIn()) {
          this.render(this.loadingTemplate); 
       } else {
          this.next(); // Done logging in? You may pass.
       }
    }
    
    var requireLogin = function() {
       if(!Meteor.user()) {
          this.render('accessDenied');
       } else {
         this.next(); // User is logged in. I'll allow it.
       }
    }
    
    // finally, use it.
    Router.onBeforeAction([userLoggingIn, requireLogin], {only: 'postSubmit'});
    Router.onBeforeAction('loading'); // built-in hook, just like dataNotFound. use in Routes with subscriptions.
    Router.onBeforeAction('dataNotFound', {only:'postPage'});
    

    Isn't that way better, and manageable? I'm not sure which order it's going to execute as I'm travelling and just typing this out at the airport.. but you can try swapping the hooks order around if it's not behaving accordingly.