React function out of scope in Accounts.createUser callback?

In the following code:

  updateErrorMessage(message) {
    this.setState({
      errorMessage: message
    })
  },
  registerUser() {
    if (this.state.password === this.state.password2) {
      Accounts.createUser({
        email: this.state.email,
        password: this.state.password
      }, function (error) {
        if (!error) {
          FlowRouter.go('/');
        } else {
          this.updateErrorMessage(error.reason);
        }
      });
    } else {
      this.updateErrorMessage("Passwords do not match.");
    }
  },

I am getting the following error when this function is executed

Exception in delivering result of invoking 'createUser': TypeError: this.updateErrorMessage is not a function

Are React functions not available in the scope of the callback?

The problem is the way JavaScript’s this works means that this.updateErrorMessage no longer refers to what you want. The best way to get around this is to use arrow functions, which are a new feature in ES2015:

  updateErrorMessage(message) {
    this.setState({
      errorMessage: message
    })
  },
  registerUser() {
    if (this.state.password === this.state.password2) {
      Accounts.createUser({
        email: this.state.email,
        password: this.state.password
      }, (error) => {   // This arrow function preserves this
        if (!error) {
          FlowRouter.go('/');
        } else {
          this.updateErrorMessage(error.reason);
        }
      });
    } else {
      this.updateErrorMessage("Passwords do not match.");
    }
  },

Arrow functions preserve the this context of the place where the function was created - in this case, your React component method.

3 Likes

Hah! I had the opposite problem yesterday and you helped me out!

Works now. Thanks Sashko!