joi
joi copied to clipboard
Live password_confirmation validation not working
Support plan
- is this issue currently blocking your project? (yes/no): no
- is this issue affecting a production system? (yes/no): yes
Context
- node version: 16.5.0
- module version with issue: 17.4.2
- last module version without issue: Never used it before, i don't know
- environment (e.g. node, browser, native): browser
- used with (e.g. hapi application, another framework, standalone, ...): react 17.0.2
- any other relevant information:
What are you trying to achieve or the steps to reproduce?
I have a password
and a password_confirmation
fields that I want to validate as the user is typing, and this is the schema:
const schema = Joi.object({
// ...
password: Joi.string()
.min(6)
.max(15)
.required()
.label("Password")
.messages({
"string.base": "Invalid password",
"string.min": "Password is too short (min {{#limit}})",
"string.max": "Password is too long (max {{#limit}})",
"string.empty": "Password is required",
"any.required": "Password is required",
}),
password_confirmation: Joi.string()
.required()
.equal(Joi.ref("password"))
.label("Confirm password")
.messages({
"any.required": "Password confirmation is required",
"string.empty": "Password confirmation is required",
"any.only": "Password does not match",
}),
});
const validationValues = {
full_name: name,
email: email,
password: password,
password_confirmation: passwordConfirmation,
};
Then for each field I do live validation such as:
<form onSubmit={handleSubmit}>
// ...
<input
name="password"
type="password"
className="form-control form-control-lg"
onChange={(event) => {
// ...
validateField(event.target);
}}
/>
// ...
<input
name="password_confirmation"
type="password"
className="form-control form-control-lg"
onChange={(event) => {
//...
validateField(event.target);
}}
/>
// ...
<button type="submit" className="btn btn-primary mt-2 mb-2">Register</button>
</form>
The password_confirmation should display an error if the two passwords don't match, and it works perfectly when I click the button to submit the entire form.
Here's the validation functions:
const validateForm = () => {
const { error } = schema.validate(validationValues, schemaOptions);
// ...
};
const validateField = ({ name, value }) => {
const fieldValue = { [name]: value };
const fieldSchema = Joi.object({ [name]: schema.extract(name) });
const { error } = fieldSchema.validate(fieldValue);
// ...
};
What was the result you got?
The problem is that it does not validate the field password_confirmation
while i am typing. Even when I match the password
field, the validation still returns a mismatch error.
What result did you expect?
When I type the same value in password_confirmation
, this error
should be null:
const { error } = fieldSchema.validate(fieldValue);
###Demo
- Go here: https://portaldev.northstarsystems.ca/register
- Enter
aaaaaa
in the password field - Start typing
a
in password_confirmation - The live validation starts working (it says "Password does not match")
- Enter the the same value
aaaaaa
- The live validation stops working (still says "Password does not match" even if they do)
- Press the Register button
- The validation worked now, the error is gone
If you are validating the field in complete isolation (your validateField
function), it is indeed normal that it won't work, it cannot compare a field to another one that doesn't exist. Validating the whole form with abortEarly: false
and only retaining the errors interesting to you is probably a better strategy.
No activity, closing, feel free to reopen if there is more to discuss.