Dan
Dan

Reputation: 75

Submit works with second try

I am validating some details, the problem is when the validation is complete and I want to move to the next page with submit, the first time it's receiving the data, and the second time it's checking if the data is true and moves me to the next page.

I have tried to put all the validation process to the OnChange function, but it messes up all of the validation process, I have also tried to put the error variables to the state but I receive an error message that It's constant variables and can't be changed.

import { Link } from 'react-router-dom';

class Profile extends Component {
  state = {
    details: {
      firstName: '',
      lastName: '',
      id: '',
      email: ''
    },
    error: false,
    complete: false
  };

  OnSubmit = e => {
    e.preventDefault();
    let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    const { email } = this.state.details;
    const { firstName } = this.state.details;
    const { lastName } = this.state.details;
    const { id } = this.state.details;
    let errorid = false;
    let errorfirstlast = false;
    let erroremail = false;

    if (id.length <= 9 && id !== '') {
      console.log('trueid');
      errorid = false;
    } else {
      errorid = true;
      console.log('falseid');
    }

    if (re.test(email)) {
      console.log('trueemail');
      erroremail = false;
    } else {
      erroremail = true;
      console.log('falseemail');
    }

    if (
      firstName !== '' &&
      lastName !== '' &&
      firstName.substr(0, 1) === firstName.substr(0, 1).toUpperCase() &&
      lastName.substr(0, 1) === lastName.substr(0, 1).toUpperCase() &&
      !firstName.match(/\d/) &&
      !lastName.match(/\d/)
    ) {
      console.log('truefirstlast');
      errorfirstlast = false;
    } else {
      errorfirstlast = true;
      console.log('falsefirstlast');
    }
    if (erroremail === true || errorfirstlast === true || errorid === true) {
      this.setState({ error: true });
    } else {
      this.setState({ error: false });
      this.setState({ complete: true });
    }
  };

  OnChange = e => {
    e.preventDefault();
    this.setState({
      details: { ...this.state.details, [e.target.name]: e.target.value }
    });
  };

  render() {
    return (
      <div>
        <div className="container text-center mt-4" style={{ width: '500px' }}>
          <form className="px-4 py-3" onSubmit={this.OnSubmit}>
            <div className="form-group">
              {this.state.error === true ? (
                <p className="text-danger">
                  Some of the details are wrong check the fields above
                </p>
              ) : null}
              <label>First Name:</label>
              <input
                type="text"
                className="form-control"
                onChange={this.OnChange}
                name="firstName"
              />
            </div>
            <div className="form-group">
              <label>Last Name:</label>
              <input
                type="text"
                className="form-control"
                onChange={this.OnChange}
                name="lastName"
              />
            </div>
            <div className="form-group">
              <label>ID Number:</label>
              <input
                type="text"
                className="form-control"
                onChange={this.OnChange}
                name="id"
              />
            </div>
            <div className="form-group">
              <label>Email:</label>
              <input
                type="text"
                className="form-control"
                onChange={this.OnChange}
                name="email"
              />
            </div>
            {this.state.complete === true ? (
              <Link to="/success">
                <button type="submit" className="btn btn-secondary mt-3">
                  Check
                </button>
              </Link>
            ) : (
              <button type="submit" className="btn btn-secondary mt-3">
                Check
              </button>
            )}
          </form>
        </div>
      </div>
    );
  }
}

export default Profile;

The problem is that I enter the next page with the second click on the submit button, I want to enter with the first try

Upvotes: 0

Views: 467

Answers (1)

ChrKahl
ChrKahl

Reputation: 651

The reason is that this.setState(..) is an async function Reference here. Moreover you're calling multiple state-operations behind each other instead of putting it in one call like:

if (erroremail === true || errorfirstlast === true || errorid === true) {
  this.setState({ error: true });
} else {
  this.setState({
    error: false,
    complete: true
  });
}

If you want to to an action after this state operation is done you can add a callback to the operation:

if (erroremail === true || errorfirstlast === true || errorid === true) {
  this.setState({ error: true });
} else {
  this.setState({
    error: false,
    complete: true
  }, this.submitMyStuff);
}

const submitMyStuff = () => {
  // submit all my stuff
}

Upvotes: 2

Related Questions