0

Following is my ReactJs code for SignIn page and for some reason, I'm getting the error "Cannot read property 'setState' of undefined" error. Basically what I am trying to do is, a user can click the remember me box and that data should get store for the next time.

Could anyone suggest how I could update this?

import React, {Component} from "react";
import axios from 'axios';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom';
import {SignUp} from "./SignUp";
import {ForgotPassword} from "./ForgotPassword";

export class SignIn extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     fields: {},
     errors: {}
    }
    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.handleCheckboxChange.bind(this);
  }

  handleValidation() {
    let fields = this.state.fields;
    let errors = {};
    let formIsValid = true

    //Email
    if(!fields["email"]) {
     formIsValid = false;
     errors["email"] = "Email ID is required";
    }

   //Password
   if(!fields["password"]) {
      formIsValid = false;
      errors["password"] = "Password is required";
   }

   this.setState({errors: errors});
   return formIsValid;
 }

  getInitialState() {
    return {
      isChecked: true
    };
  }

  handleCheckboxChange(event) {
    console.log("checkbox changed!", event);
    this.setState({isChecked: event.target.checked});
  }


  onSubmit(e) {
    e.preventDefault();
    if(this.handleValidation()) {
      var apiBaseUrl = "http://rediy-dev.railsfactory.com/";
      var input = this.state.fields;
      axios.post(apiBaseUrl+'/api/v1/sessions/login', input)
      .then(function (response) {
         console.log(response);
         if(response.data.status == 200) {
           console.log("Login successful");
           alert("Login successful");
         }
         else if(response.data.status == 422) {
           console.log("Invalid user details. Please enter again");
           alert("Invalid user details. Please enter again");
         }
       })
       .catch(function (error) {
         console.log(error);
       });
     }
   }

  onChange(field, e) {
    let fields = this.state.fields;
    fields[field] = e.target.value;
    this.setState({fields});
  }


  render() {
    return (
      <div id="login" className="form-popup" role="dialog">
        <div className="modal-dialog">
          <div className="modal-content">
            <form className="form-theme text-left">
              <div className="modal-header">
                <button type="button" className="close" data-dismiss="modal">&times;</button>
                <h1 className="theme-title text-center">Sign In</h1>
              </div>
              <div className="modal-body">
                <div className="row">
                  <div className="col-sm-12">
                    <div className="form-group input">
                      <input
                        value={this.state.fields["email"]}
                        onChange={this.onChange.bind(this, "email")}
                        className="form-control input__field"
                        type="text"
                        id="unit"
                        refs="email"
                        placeholder="Email Id *"
                      />
                      <span style={{color: "red"}}>{this.state.errors["email"]}</span>
                    </div>
                  </div>
                  <div className="col-sm-12">
                    <div className="form-group input">
                      <input
                        value={this.state.fields["password"]}
                        onChange={this.onChange.bind(this, "password")}
                        className="form-control input__field"
                        type="text"
                        id="unit"
                        refs="password"
                        placeholder="Password *"
                      />
                      <span style={{color: "red"}}>{this.state.errors["password"]}</span>
                    </div>
                  </div>
                  <div className="col-sm-6">
                    <div className="forgot-password">
                      <p> <Link to="/ForgotPassword">Forgot your password</Link></p>
                    </div>
                  </div>
                  <div className="col-sm-6">
                    <div className="register">
                      <p>New User? <Link to="/SignUp">Register</Link></p>
                    </div>
                  </div>
                  <div className="col-sm-12">
                    <div className="checkbox checkbox-primary">
                      <input
                        onChange={this.handleCheckboxChange}
                        checked={this.state.isChecked}
                        type="checkbox"
                        id="checkbox1"
                      />
                      <label htmlFor="checkbox1">
                        Remember Me
                      </label>
                    </div>
                  </div>
                </div>
              </div>
              <div className="modal-footer">
                <div className="btn-wrap">
                  <button type="submit" className="btn btn-theme save btn btn-primary" onClick={this.onSubmit}>Sign In</button>
                  <button type="submit" className="btn btn-theme btn btn-danger" data-dismiss="modal">Cancel</button>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    );
  }
}
Riya Kapuria
  • 9,170
  • 7
  • 18
  • 32
  • 3
    Possible duplicate of [Uncaught TypeError: Cannot read property 'setState' of undefined](https://stackoverflow.com/questions/32317154/uncaught-typeerror-cannot-read-property-setstate-of-undefined) – Chris Oct 12 '17 at 07:19
  • 1
    Why would anyone up-vote an obvious duplicate? – Chris Oct 12 '17 at 07:25
  • @Andrew I don't see `this.handleValidation = this.handleValidation.bind(this);` anywhere in the constructor. – Chris Oct 12 '17 at 08:54
  • @Chris This is not a duplicate of that post. Pay attention to the constructor. The author is using `bind` correctly. – Andrew Oct 12 '17 at 08:54
  • @Andrew, yes, but only for 2 methods. Not for all. See my comment above. – Chris Oct 12 '17 at 08:55
  • @Chris `handleValidation` is inside `onSubmit`, which is already properly bound, isn't it? I guess I could be wrong. Aside from that, you should answer it. This isn't a question about fundamentals. It's a silly mistake/oversight. – Andrew Oct 12 '17 at 08:56
  • @Andrew, it's only invoked from `onSubmit`, it still has the incorrect reference to `this`. – Chris Oct 12 '17 at 08:58
  • problem is only with handleCheckboxChange not with handleValidation – Riya Kapuria Oct 12 '17 at 09:18
  • can you please give me some idea how to create remember me in this sign up page – Riya Kapuria Oct 12 '17 at 09:28

1 Answers1

1
<input
   onChange={this.handleCheckboxChange}
   checked={this.state.isChecked}
   type="checkbox"
   id="checkbox1"
   />
this.onChange = this.handleCheckboxChange.bind(this); //from your constructor

Looks like you accidentally spliced two of your binds together. It needs to be this, obviously:

this.handleCheckboxChange= this.handleCheckboxChange.bind(this);
this.onChange = this.onChange.bind(this);
Andrew
  • 7,201
  • 5
  • 25
  • 34