Reputation: 4017
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;
};
Upvotes: 2
Views: 2118
Reputation: 6742
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?
Upvotes: 4