farooq
farooq

Reputation: 1673

Cannot read property 'setState' of undefined even after defining bind(this.submit)

I've been working on react js and want to setState for response from firebase.
So when I'm trying to set value for state, it returns the error ,

Cannot read property 'setState' of undefined

My code.

class Login extends Component {
    constructor(props) {
        super(props)
        this.state = {email:'',
                    uid:'',
                    password :'',
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.signInWithGoogle = this.signInWithGoogle.bind(this)
    }
    handleChange(event) {
        this.setState({
            [event.target.id] : event.target.value
        })
        console.log(this.state.email)
        console.log(this.state.password)
      }
      handleSubmit(e) {
        e.preventDefault()
        firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(function(result)  {
            console.log(result.user.uid)
            this.setState({ [uid]: [result.user.uid] });
        }).catch(function(error) {
            console.log(error.code)
            console.log(error.message)
            alert(error.message)
           })
      }

I do have a form to give inputs . Can somebody help me on this .

Upvotes: 1

Views: 107

Answers (6)

eduard
eduard

Reputation: 67

Update your handleSubmit() function as followed :

handleSubmit(e) {
       e.preventDefault()
       firebase.auth().signInWithEmailAndPassword(this.state.email, 
       this.state.password).then((result) => {
         console.log(result.user.uid)
         this.setState({ uid: result.user.uid });
       }).catch(function(error) {
         console.log(error.code)
         console.log(error.message)
         alert(error.message)
       })
     }

Upvotes: 1

fxnoob
fxnoob

Reputation: 176

Actual Answer was provided to the query. I want to say that you can use arrow function syntax to bind functions automatically.

e.g.

handleSubmit = (e) => {
       e.preventDefault()
       firebase.auth().signInWithEmailAndPassword(this.state.email, 
       this.state.password).then((result) => {
         console.log(result.user.uid)
         this.setState({ uid: result.user.uid });
       }).catch(function(error) {
         console.log(error.code)
         console.log(error.message)
         alert(error.message)
       })
     }

So you would not have to write

this.handleSubmit = this.handleSubmit.bind(this)

Upvotes: 1

Amit Chauhan
Amit Chauhan

Reputation: 1884

Please update your handleSubmit function like this

      handleSubmit(e) {
       e.preventDefault()
       firebase.auth().signInWithEmailAndPassword(this.state.email, 
       this.state.password).then((result) => {
         console.log(result.user.uid)
         this.setState({ uid: result.user.uid });
       }).catch(function(error) {
         console.log(error.code)
         console.log(error.message)
         alert(error.message)
       })
     }

this scope is only available inside the fat arrow function () => {}, so I have just updated your function

firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(function(result)  {

to

firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then((result) =>  {

Upvotes: 1

0xAnon
0xAnon

Reputation: 897

in the second setState method inside firebase signInWithEmailAndPassword you are using anonymous function which has it's own this scope. so the this.setState will take the reference inside the function itself and not the class this. In order to make sure your setState gets the lexical this of the class , you would have to use arrow function :

  firebase
   .auth()
   .signInWithEmailAndPassword(this.state.email, this.state.password)
   .then((result) => { // arrow function used
        console.log(result.user.uid)
        this.setState({ [uid]: [result.user.uid] });
   })

You can also use @Sukrut Bam answer explanation as one of your methodology

Upvotes: 1

Sukrut Bam
Sukrut Bam

Reputation: 87

You need to write const that = this; as a first line in your handleSubmit method and use that instead of this in your function.

Upvotes: 1

Swaroop Deval
Swaroop Deval

Reputation: 906

You can either use arrow function or store this in another variable.

Method 1:

handleSubmit(e) {
    e.preventDefault()
    firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then((result) => {
        console.log(result.user.uid)
        this.setState({ [uid]: [result.user.uid] });
    }).catch(function(error) {
        console.log(error.code)
        console.log(error.message)
        alert(error.message)
    })
}

Method 2

 handleSubmit(e) {
    e.preventDefault()
    let _this = this;
    firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(function(result)  {
        console.log(result.user.uid)
        _this.setState({ [uid]: [result.user.uid] });
    }).catch(function(error) {
        console.log(error.code)
        console.log(error.message)
        alert(error.message)
    })
}

Upvotes: 1

Related Questions