For this "flat" object validation
const fields = [
{label: 'Name', name: 'name', validation: yup.string().required()},
{label: 'City', name: 'city', validation: yup.string().required()},
{label: 'Phone', name: 'phone'},
]
I created createYupSchema
function to get Yup schema object from fields
.
const createYupSchema = (fields ) => {
const schema = fields.reduce((schema, field) => {
return field.validation
? {...schema, [field.name]: field.validation}
: schema
}, {})
return yup.object().shape(schema)
}
The output is Yup object:
yup.object().shape({
name: yup.string().required(),
city: yup.string().required(),
})
But I would to have the possibility to use also nested object in fields
const fields = [
{label: 'Name', name: 'name', validation: yup.string().required()},
{label: 'Address', name: 'address.city', validation: yup.string().required()},
{label: 'Phone', name: 'phone'},
]
So the Yup object should be:
yup.object().shape({
name: yup.string().required(),
address: yup.object().shape({
city: yup.string().required()
}),
})
Is it possibile to create this type of Yup object from fields
?
I resolved my question. Now createYupSchema
works in this way
const createYupSchema = fields => {
const schema = fields.reduce((schema, field) => {
const isObject = field.name.indexOf(".") >= 0;
if (!field.validation) {
return schema;
}
if (!isObject) {
return { ...schema, [field.name]: field.validation };
}
const reversePath = field.name.split(".").reverse();
const currNestedObject = reversePath.slice(1).reduce((yupObj, path) => {
return { [path]: yup.object().shape(yupObj) };
}, {[reversePath [0]]: field.validation});
return { ...schema, ...currNestedObject };
}, {});
return yup.object().shape(schema);
};
I resolved my question, using the "lazy" method:
const validateSchema = Yup.object().shape({
items: Yup.array().of(
Yup.lazy((item) => {
return Yup.object({
itemName: Yup.string().test(
'validate',
'warning',
(value) => {
if (value && item.itemDescription) return true
if (!value && !item.itemDescription) return true
return false
}
),
itemDescription: Yup.string().test(
'validate',
'warning',
(value) => {
if (value && item.itemName) return true
if (!value && !item.itemName) return true
return false
}
),
})
})
),
})
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