javascriptmeteordatabase-designmeteor-blazeflow-router

Meteor, define "standard route" for each user


I'm currently working on some kind of todo app. I can easily navigate to any list by accessing the id parameter in the url and then pass this to flowrouter, no problem. But now I want a default list like "inbox" to be always the first screen when navigating to localhost:3000, so route "/". I've a database called "lists" where I save all lists in, also the list "inbox". But how can I define my route to navigate to http://localhost:300/lists/idOfListInbox when visiting "/"?. I thought about saving the id of this special list in my profile, but that doesn't work because Meteor.user() is not available with own top level fields in the action part of flowrouter and I don't want to use sessions or cookies. Anyone an idea how to solve this?


Solution

  • Assuming you use kadira:flow-router you can define a trigger on enter. This function runs before the page is rendered and allows to to check some states, e.g. if user is logged in. This also allows to get the inbox id for the current user.

    To do this, you need a meteor method. This method also checks, whether the current user is a logged in and registered user (because Meteor.user() in the client can always be manipulated.) If it is a valid iser, the method retrieves the user's list document and returns it's _id.

    Meteor.methods({
        'getListByUser'() {
            // check user permission
            if (!this.userId || !Meteor.users.findOne(this.userId))
                throw new Error("permission denied");
            // get listId by userId
            return Lists.findOne({userId:this.userId})._id;
        }
    });
    

    Note: this is just an example, that assumes, that each list document is connected with a user via a field, named userId. In your case you need to get the list for the user in your specific way.

    The corresponding route then calls on triggersEnter the server method to obtain the listId and redirect the user to his/her inbox.

    FlowRouter.route('/', {
      // calls just before the action
      triggersEnter: [function(){
          Meteor.call("getListByUser", function(err, listId) {
              if (err) { /* handle err */ }
              if (listId) redirect('/lists/'+listId);
          });
      }],
      action: function() {
        // do something you like
      },
    });
    

    This could be one solution by using triggers enter. There is another design, where you would integrate the lists template inside the template you render in your / (root) path, once you have loaded the listId from the method within the root path's template. I discourage that because it takes away some flexibility, where you hard link two templates with each other.