Ahmed Refaat
Ahmed Refaat

Reputation: 93

TypeError: Cannot read property 'validate' of undefined

I am trying to validate my registration form but I'm getting this error and I can't solve it. my form submit button goes to handleRegistration which should validate the form first then submit. I was trying to follow the example in this link https://www.itsolutionstuff.com/post/password-and-confirm-password-validation-in-reactexample.html

handleRegistration(event) {
  event.preventDefault();
  if (this.validate()) {
    this.toggleModal();
    console.log(this.state);
    let input = {};
    input["name"] = "";
    input["email"] = "";
    input["password"] = "";
    input["confirmPassword"] = "";
    input["age"] = "";
    input["gender"] = "";
    this.setState({
      input: input
    });
    console.log(this.state)
    alert('Demo Form is submited');
  }
}

validate() {
  let input = this.state.input;
  let errors = {};
  let isValid = true;

  if (!input["fullname"]) {
    isValid = false;
    errors["fullname"] = "Please enter your name.";
  }

  if (!input["email"]) {
    isValid = false;
    errors["email"] = "Please enter your email Address.";
  }

  if (typeof input["email"] !== "undefined") {

    var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
    if (!pattern.test(input["email"])) {
      isValid = false;
      errors["email"] = "Please enter valid email address.";
    }
  }

  if (!input["password"]) {
    isValid = false;
    errors["password"] = "Please enter your password.";
  }

  if (!input["confirmPassword"]) {
    isValid = false;
    errors["confirmPassword"] = "Please confirm your password.";
  }

  if (!input["age"]) {
    isValid = false;
    errors["age"] = "Please Enter your age.";
  }

  if (typeof input["password"] !== "undefined" && typeof input["confirmPassword"] !== "undefined") {

    if (input["password"] != input["confirmPassword"]) {
      isValid = false;
      errors["password"] = "Passwords don't match.";
    }
  }

  this.setState({
    errors: errors
  });

  return isValid;
}

handleChange(event) {
  let input = this.state.input;
  input[event.target.name] = event.target.value;

  this.setState({
    input
  });
}

I am initalizing my input and errors objects in my state here

this.state = {
  isNavOpen: false,
  isModalOpen: false,
  isRegistrationModalOpen: false,
  input: {},
  errors: {}
}

and my registration form is structured like that

<Form onSubmit={this.handleRegistration}>
  <FormGroup>
    <Input type="text" id="fullname" name="fullname" placeholder="Full Name" value={this.state.input.name} onChange={this.handleChange}></Input>
    <div className="text-danger">{this.state.errors.name}</div>
  </FormGroup>
  ....
</Form>

Thank you

Upvotes: 1

Views: 22883

Answers (1)

Mosh Feu
Mosh Feu

Reputation: 29249

The problem

<Form onSubmit={this.handleRegistration}>

this.handleRegistration wasn't bound to the class (component) therefor this doesn't refer to the class instance.

The solution

Declare the method as arrow function. This way it will be the instance method but not on the prototype so this will refer to the instance.

handleRegistration(event) {

to

handleRegistration = (event) => { 

More info: https://reactjs.org/docs/faq-functions.html#class-properties-stage-3-proposal.

Upvotes: 2

Related Questions