Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting on Meteor.user()

If a new users signs up, I take them to the getting started route so they enter can enter a name which is at /gs. I store the name inside a name property of the profile object of the current user. Now if a user who has already entered a name and visits the /gs route I want to redirect them to the root. In iron router, I do this:

Router.route('/gs', {
  name: 'gs',
  onBeforeAction: function() {
    if ( Meteor.user().profile.name ) {
      this.redirect('/');
    } else {
      this.render();
    }
  }
});

Even though this works, it prints out 2 errors to the console. One of them being "Cannot read property 'profile' of undefined" and the lack of this.next(). Any way to fix these problems.

like image 366
fardeem Avatar asked Dec 14 '14 09:12

fardeem


1 Answers

Your route functions and most hooks are run in a reactive computation. This means they will rerun automatically if a reactive data source changes. For example, if you call Meteor.user() inside of your route function, your route function will rerun each time the value of Meteor.user() changes. (Iron.Router Guide: Reactivity)

Hook functions and all functions that get run when dispatching to a route are run in a reactive computation: they will rerun if any reactive data sources invalidate the computation. In the above example, if Meteor.user() changes the entire set of route functions will be run again. (Iron.Router Guide: Using Hooks)

The first time the function is run, Meteor.user() is undefined. Then its value change to an object. As it is a reactive variable, the function is run again, without error this time.

You should check if Meteor.user() is defined before using its properties. Here is a very (maybe too much) exhaustive way of doing so:

if (Meteor.user() !== undefined) {
  // the user is ready
  if (Meteor.user()) {
    // the user is logged in
    if (Meteor.user() && Meteor.user().profile.name) {
      // the name is already set
      this.redirect('/');
    } else {
      this.render();
  } else {
    // the user is not logged in
} else {
  // waiting for the user to be ready
}
like image 77
pandark Avatar answered Sep 29 '22 06:09

pandark