As far as i can tell, there is no method that allows to specify an attribute as optional.
My issue is the following
const subSchema = {
foo: yup.string().required()
}
const schema = yup.object().shape({
optional: yup.object().shape(subSchema),
required: yup.required().shape(subSchema)
})
When i validate schema, omitting optional will fail, because optional.foo is required.
It seems kinda limiting that i cannot control optional (and in my logic, the required() method appended to any attribute in the shape should control if its required, not the required methd inside the subSchema).
A i just missing the point here, or is the not possible at the moment?
Fields are optional by default, but when not strict mode, the value is cast when validating which will use the _default_ value when the value is empty so:
const subSchema = {
foo: yup.string().required()
}
const schema = yup.object().shape({
optional: yup.object().shape(subSchema),
required: yup.object().shape(subSchema).required()
})
schema.isValid({ required: { foo: 'foo' } }, { strict: false }) // false
schema.isValid({ required: { foo: 'foo' } }, { strict: true }) // true
object schema have built in defaults where they construct an object from their shape, so
yup.object({
foo: string().default('bar')
})
.default() // => { foo: 'bar' }`.
The reason is that the first case above fails, is that optional, being empty, uses its default() which is: {} now that the value isn't empty foo gets validated, is missing and fails.
if you set the default to undefined (i.e. remove it) it would work like you expect.
const schema = yup.object().shape({
optional: yup.object().shape(subSchema).default(undefined),
required: yup.object().shape(subSchema).required()
})
schema.isValid({ required: { foo: 'foo' } }) // true
Joi has a option to validate without using default values, that I have been thinking of adding as well...
That makes sense.. :)
I solved it by applying a custom test
optional: object().test('valid object', 'not valid', value => {
if (value === undefined) {
return true;
} else {
return object().shape(subSchema).validate(value);
}
})
But the default method is better..
Thanks for clarifying..
@jquense Consider adding something about default(undefined) on object to the documentation. Just ran into this myself and luckily found this ticket =)
makes sense, PRs welcome! :)
Most helpful comment
Fields are optional by default, but when not strict mode, the value is cast when validating which will use the _default_ value when the value is empty so:
object schema have built in defaults where they construct an object from their shape, so
The reason is that the first case above fails, is that
optional, being empty, uses itsdefault()which is:{}now that the value isn't emptyfoogets validated, is missing and fails.if you set the default to
undefined(i.e. remove it) it would work like you expect.Joi has a option to validate without using default values, that I have been thinking of adding as well...