2

I have a regex which validates the password provided by use in a form, the password must be 6 characters long, 1upper case, 1 lower case, 1 numerical and 1 special character.
Below is the react component for the form:

import React from "react";
import { passwordRegex } from "./Constants";

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      email: null,
      password: null,
      disableSubmitButton: true
    };
  }

  formData = {
    email: "",
    password: ""
  };

  componentWillUpdate(nextProps, nextState) {
    nextState.disableSubmitButton = !(nextState.email && nextState.password);
  }

  initializeFormData = () => {
    this.formData = {
      email: this.state.email,
      password: this.state.password
    };
  };

  verifyFormData = () => {
    if (!passwordRegex.test(this.formData.password)) {
      console.error("invalid password");
      return false;
    }

    return true;
  };

  submitForm = event => {
    event.preventDefault();
    const ifFromValid = this.verifyFormData();
    console.log(ifFromValid);
  };

  render() {
    this.initializeFormData();
    return (
      <form onSubmit={this.submitForm}>
        <br />
        <label htmlFor="email">Email </label>
        <input
          type="text"
          onChange={event => {
            this.setState({ email: event.target.value });
          }}
        />
        <br />
        <label htmlFor="password" name="password">
          Password
        </label>
        <input
          type="password"
          onChange={event => {
            this.setState({ password: event.target.value });
          }}
        />
        <br />
        <input type="submit" name="submit" id="submit"
          disabled={this.state.disableSubmitButton}
        />
      </form>
    );
  }
}

Constants.js

export const passwordRegex = new RegExp(
  "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{6,}$",
  "g"
);

Problem:
The form validation works fine on the first submit, then on further submit clicks, the regex behave abnormally. Sometimes it enters to the if (!passwordRegex.test(this.formData.password)) block and sometimes doesn't enter.

The weird thing is: the same code works very perfectly if I create a local variable for passwrodRegex inside the verifyFormData() function:

      verifyFormData = () => {
        const passwordRegex = new RegExp("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{6,}$","g");
        if (!passwordRegex.test(this.formData.password)) {
          console.error("invalid password");
          return false;
        }

        return true;
      };
3
  • Encoding of the file maybe? Check it. Commented Sep 4, 2018 at 9:49
  • @CodeCrusha which file? Commented Sep 4, 2018 at 9:51
  • Both. The file, which contains the regex, need to have the correct file-encoding. The other file is not that important, but should also have the same file encoding. I guess that is the problem, if not, let me know. Commented Sep 4, 2018 at 9:53

1 Answer 1

4

I think your problem is, bizarrely, the 'g' flag.

Try this:

passwordR = new RegExp("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{6,}$","g");
console.log(passwordR.test('As!df2L$'));
console.log(passwordR.test('As!df2L$'));

The output will surprise you. It surprised me, anyway. (Spoiler, it's true false)

Now have a look at this: JavaScript RegExp cant use twice?

The headline is "RegExp instances have state when you use the g flag".

Finally, see if your code works as expected if you remove the g flag.

I've also found this, which has similar information: Why does a RegExp with global flag give wrong results?

Sign up to request clarification or add additional context in comments.

2 Comments

great. That worked like charm. BTW it's little weird to me that regex also have state, since I am from Java background
I think it's weird to a lot of people, whether from a Java background or not. But the js spec does hide some surprises.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.