Home > Software design >  Yup keeps running validators on the same property when .required() is false
Yup keeps running validators on the same property when .required() is false

Time:01-15

I'm a bit confused about how yup is working.

I have the following schema to validate the register

export const registerValidationSchema = yup.object().shape({
    first_name: yup.string().trim().required(),
    last_name: yup.string().trim().required(),
    date_of_birth: yup.date().required().test('DOB', 'You must be at least 18 to register', value => {
        return value.setFullYear(value.getFullYear()   18) < Date.now()
    }),
    email: yup.email().trim().required()
});

When the object to validate is the following

const data = {
    email: "[email protected]"
}

The validation will crash because value is undefined and the function value.setFullYear will fail. But why? I assume that yup will stop this line on .required() part and go to the next property.

I know the issue can be fixed by adding if(!value) return false; inside .test() but what's the point of the required function?

From the yup documentation:

string.required(message?: string | function): Schema

The same as the mixed() schema required, except that empty strings are also considered 'missing' values.

mixed.required(message?: string | function): Schema

Mark the schema as required, which will not allow undefined or null as a value. Note that unless a schema is marked as nullable() a null value is treated as a type error, not a missing value. Mark a schema as mixed().nullable().required() treat null as missing.

So I read this as an undefined, null or '' value should fail on the .required() rule.

CodePudding user response:

I'm using the below yup.mixed construction when more fine-grained control is required. E.g. when validating FileList. Hopefully, it will bring you one step further.

date_of_birth: yup.mixed()
    .test(
        "required",
        "Date of birth is required",
        (dateOfBirth) => ... return true if dateOfBirth is not null/undefined and is a valid date, else false
    ).test(
        "DOB",
        "You must be at least 18 to register",
        (dateOfBirth) => ... do the above-eighteen-check and return true/false 
    )

CodePudding user response:

Instead of email: yup.email().trim().required()
Try email: yup.string().trim().email().required()

found in github documentation

const registerValidationSchema = yup.object().shape({
  first_name: yup.string().trim().required(),
  last_name: yup.string().trim().required(),
  date_of_birth: yup.date().required().test('DOB', 'You must be at least 18 to register', value => {
    return value.setFullYear(value.getFullYear()   18) < Date.now()
  }),
  // email: yup.email().trim().required
  // modified
  email: yup.string().trim().email().required()
})

const data = {
  first_name: "john",
  last_name: "deo",
  date_of_birth: "12-jan-2000",
  email: " [email protected] "
}

// validating schema
registerValidationSchema.isValid(data)
  .then(r => console.log(r))
  .catch(e => console.log(e))
  • Related