JavaScript Undefined is not a function this.setState undefined the function

I created a simple login page, which, once the button is pressed, executes this function :

login = (email, password, navigate) => {
  this.setState({ loginButtonPressed: true });
  firebase
    .auth()
    .signInWithEmailAndPassword(email, password)
    .then(function(user) {
      navigate('Profile');
    })
    .catch(function(error) {
      this.setState({ loginButtonPressed: false });
      Alert.alert(error.toString());
    });
};

Once called, it executes "this.setState({ loginButtonPressed: true })" since the button changes shape (it is marked as pressed). But I get the following error: Undefined is not a function this.setState.

How can this be fixed? Thanks for your help.

Answer:1

The problem is with:

.catch(function(error) {
  this.setState({ loginButtonPressed: false });
  Alert.alert(error.toString());
});

you create an anonymous function where this will reference this anonymous function (Object), not a React Object.

I see you can use arrow functions, so fix it like:

.catch((error) => {
  this.setState({ loginButtonPressed: false });
  Alert.alert(error.toString());
});

With arrow function this will reference context in which it is used.

Answer:2

Or you can keep a copy of the reference to this, like this:

const self = this; (first line in your function);

and use "self" instead of "this" anywhere in the function.

You can use this in places where you might not be able to use arrow functions.

Answer:3

You need to bind to this in order to have access inside the callback. Try it with the arrow functions.

Answer:4

Are you extending react component?

If you are not you will need to do that to utilize setState, if you are you will need to be sure to create the state in a constructor before you update it with setState elsewhere.

Something along the lines of:

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loginButtonPressed: false };
    this.login = this.login.bind(this);
  }

  login(email, password, navigate) {
    this.setState({ loginButtonPressed: true });
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(function(user) {
        navigate('Profile');
      })
      .catch(function(error) {
        this.setState({ loginButtonPressed: false });
        Alert.alert(error.toString());
      });
  };

  render() {
    return (
      <Button onClick={this.logIn}>Login</Button>
    );
  }
}
Answer:5

I need to show the caption div when current item is focused. i am able to show the caption but when second last image focused with cation last image also show caption in loop. In first loop all ...

I need to show the caption div when current item is focused. i am able to show the caption but when second last image focused with cation last image also show caption in loop. In first loop all ...

I often read that I should not use HTML's onclick attribute because it decrease code readability. Instead I should make event listener in my script.js. So what do you think about v-on:click? Is it ...

I often read that I should not use HTML's onclick attribute because it decrease code readability. Instead I should make event listener in my script.js. So what do you think about v-on:click? Is it ...

I'm working on the router in Vue js. I display the current link in Navbar by adding style for router-link-active and exact property for each <router-link>. It's work fine. But now I'm trying to ...

I'm working on the router in Vue js. I display the current link in Navbar by adding style for router-link-active and exact property for each <router-link>. It's work fine. But now I'm trying to ...

If body is smaller than viewport, then the viewport size is returned. What I am trying to do is resize a picture so that the body fits inside the viewport. I want to have one of those nice "above the ...

If body is smaller than viewport, then the viewport size is returned. What I am trying to do is resize a picture so that the body fits inside the viewport. I want to have one of those nice "above the ...