I am trying to write a custom test for the yup validation library for use in a node/express app that tests whether two fields are the same - use case e.g. testing whether password and confirm password fields match. The logic is working, however the message provided from the method is not.
Custom validator code modified from: https://github.com/jquense/yup/issues/97#issuecomment-306547261
Custom validator
yup.addMethod(yup.string, 'isMatch', function (ref, msg) {
return this.test({
name: 'isMatch',
message: msg || `${this.path} must be equal to ${this.reference}`,
params: {
reference: ref.path
},
test: function (value) {
return value === this.resolve(ref);
}
});
});
Example use
const schema = yup.object().shape({
password: yup.string().min(8),
passwordConfirm: yup.string().isMatch(yup.ref('password'))
})
const payload = {
password: 'correctPassword',
passwordConfirm: 'incorrectPassword'
}
schema.validate(payload)
The above method works as expected from a logic perspective. However, in the error message returned, the value of this.path and this.reference are both undefined (i.e. undefined must be equal to undefined). It should read passwordConfirm must be equal to password.
I had to add this. in front of path and reference, otherwise node crashes with a ReferenceError that path/reference is not defined.
You do not need to write a custom validation function to check if two fields match, you can use the built in validator.oneOf
Whitelist a set of values. Values added are automatically removed from any blacklist if they are in it. The ${values} interpolation can be used in the message argument.
Note that undefined does not fail this validator, even when undefined is not included in arrayOfValues. If you don't want undefined to be a valid value, you can use mixed.required.
See here ref: oneOf(arrayOfValues: Array, message?: string | function): Schema Alias: equals
So you could re-write your schema as follows (I've added required also to the password fields):
const schema = yup.object().shape({
password: yup.string().min(8).required('Required!'),
passwordConfirm: yup.string().oneOf([Yup.ref('password')], 'Password must be the same!').required('Required!')
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With