Zainul Abideen
Zainul Abideen

Reputation: 1900

Calling a function inside .then() is throwing an error

I'm trying to perform some task with firebase and calling some functions inside promise without any callback function and this is giving me an error. Here is my code

onButtonPress = () => {
  const {email, password} = this.state
  this.setState({error: '', loading: true});

  firebase.auth().signInWithEmailAndPassword(email, password)
  .then(this.onAuthSuccess().bind(this))
  .catch(()=>{
    firebase.auth().createUserWithEmailAndPassword(email, password)
    .then(this.onAuthSuccess().bind(this))
    .catch(this.onAuthFailed().bind(this))
  })
}

  onAuthSuccess() {
    this.setState({
      email: '',
      password: '',
      error: '',
      loading: false
    })
  }

  onAuthFailed() {
    this.setState({
      error: "Authentication Failed",
      loading: false
    })
  }

Here is the error message that I'm getting

undefined is not an object (evaluating '_this.onAuthSuccess().bind()')

Upvotes: 2

Views: 1042

Answers (2)

Mike Rudge
Mike Rudge

Reputation: 206

Not 100% as the good ol this context is confusing!

so I think you want to get rid of the bind() and instead use => on your functions. Using the fat arrows will reset the context of this so this.setState should be right in the context of your class based component.

Here is an example of what I mean

onAuthSuccess = () => {
  this.setState({
    email: "",
    password: "",
    error: "",
    loading: false
  });
};

onAuthFailed = () => {
  this.setState({
    error: "Authentication Failed",
    loading: false
  });
};

onButtonPress = () => {
  const { email, password } = this.state;
  this.setState({ error: "", loading: true });

   firebase
  .auth()
  .signInWithEmailAndPassword(email, password)
  .then(() => this.onAuthSuccess())
  .catch(() => {
    firebase
      .auth()
      .createUserWithEmailAndPassword(email, password)
      .then(() => this.onAuthSuccess())
      .catch(() => this.onAuthFailed());
  });
};

Upvotes: 1

Rex Low
Rex Low

Reputation: 2167

3 ways of dealing with this context in ES6.

  1. Use the bind keyword
onAuthSuccess() {
    ...
}

firebase.auth()
    .then(this.onAuthSuccess.bind(this));
    .catch(this.onAuthFailed.bind(this));
}
  1. Use arrow function to avoid prebinding
onAuthSuccess = () => {
    ...
}

firebase.auth()
    .then(this.onAuthSuccess);
    .catch(this.onAuthFailed);
}
  1. Bind your methods in the constructor
constructor(props) {
    super(props);
    this.onAuthSuccess = this.onAuthSuccess.bind(this);
}

Upvotes: 2

Related Questions