I'm facing a validation issue with Yup while using ES Modules in my Node.js project. Here’s the schema I'm using:
import * as Yup from 'yup';
const schema = Yup.object().shape({
name: Yup.string(),
email: Yup.string().email(),
oldPassword: Yup.string().min(6),
password: Yup.string()
.min(6)
.when('oldPassword', (oldPassword, field) =>
oldPassword ? field.required() : field.notRequired(),
),
confirmPassword: Yup.string().when('password', (password, field) =>
password
? field.required().oneOf([Yup.ref('password')])
: field.notRequired(),
)
});
Here's the request body I'm sending:
{
"name": "Amanda",
"email": "amanda@example.com"
}
But when I validate it using:
try {
await schema.validate(req.body, { abortEarly: false });
} catch (err) {
return res
.status(400)
.json({ error: 'Validation fails', details: err.errors });
}
I get the following error response:
{
"error": "Validation fails",
"details": [
"password is a required field",
"confirmPassword is a required field"
]
}
What I've Tried:
Explicitly marking fields as .notRequired().
Logging req.body to ensure the input matches the expected structure.
Testing the schema independently with the same input.
Additional Context:
Am I missing something in my schema definition, or could this be an issue with how Yup handles conditional logic? Any help would be greatly appreciated!
With yup is better to use is with then and otherwise for Conditional Logic this format is more explicit and reliable for handling dependencies in Yup.
Avoid Overloading Inline Functions, it’s less clear and might lead to unexpected behaviors when dealing with complex schemas.
With the following changes the code should work:
const schema = Yup.object().shape({
name: Yup.string(),
email: Yup.string().email(),
oldPassword: Yup.string().min(6),
password: Yup.string()
.min(6, 'Password must be at least 6 characters')
.when('oldPassword', {
is: (oldPassword) => !!oldPassword, // Check if oldPassword is truthy
then: (schema) => schema.required('Password is required'),
otherwise: (schema) => schema.notRequired(),
}),
confirmPassword: Yup.string()
.when('password', {
is: (password) => !!password, // Check if password is truthy
then: (schema) =>
schema
.required('Confirm password is required')
.oneOf([Yup.ref('password')], 'Passwords must match'),
otherwise: (schema) => schema.notRequired(),
}),
});
I tested it and it works for me!