Search code examples
meteormeteor-accountsmeteor-reactmeteor-tracker

How to apply Tracker.autorun? Meteor.userId() undefined right after refreshing page


I have a restricted page using Meteor.userId() and roles:

class AdminPage extends Component {
render() {
 return (
  <div>
    {
      Roles.userIsInRole(Meteor.userId(), 'admin') ? (
        <Master_Layout renderCenter={<Article_Editor />}/>
      ) : browserHistory.push('/')
    }
  </div>
)
}
}

This code redirects user to "/" after refresh because Meteor.userId() is undefined. How do I make sure Meteor.userId() is not undefined before rendering the page after refresh?

I searched for answers. I found Tracker.autorun as a solution, but I did not understand how to apply it.

Thank you for help. I updated the code:

constructor(props) {
super(props);

this.state = { user: '' };
}
componentDidMount() {
var $this = this;

Tracker.autorun(function () {
  let user = Meteor.user();
  if(user != undefined) {
    $this.setState({ user: user });
  }
});
}
render() {
if(Roles.userIsInRole(this.state.user, 'admin')) {
  return (
    <div>
      <Master_Layout renderCenter={<Article_Editor />} />
    </div>
  )
} else {
  return <div>loading...</div>
}
}
}

Observed needed parts:
$this = this;
user = Meteor.user(); //Meteor.userId() does not work.
removed browserHistory because it will navigate away before user is defined.

Now I just need to find a solution on defining user/userId before render mounts.


Solution

  • Tracker.autorun allows you a function to be called automatically whenever it's dependent reactive data source changes.

    Simply speaking, Tracker.autorun() takes a function as input, runs this function now and returns whenever the data source changes later on.

    In your case, you can use Tracker.autorun() for tracking the user document, since Meteor.user() and Meteor.userId() are reactive. In componentDidMount() call Tracker.autorun() and save the user document in elsewhere when it changes.

    Hope following code snippet helps:

    componentDidMount() {
            var context = this;
    
            Tracker.autorun(function(){
                let user = Meteor.user();
                if (user != undefined) {
                    context.setState({ user: user, });
                }
            });
        }