I'm looking to effectively do a .when('ancestor.prop.foo.bar' ....) style validation with yup. My schema is a very large/complex data model, and a lot of fields have their validations controlled by top level/nested attributes.
(side note: using mantine)
Currently I have been able to replace mantine's 'yupResolver' function with my own implementation which appends the schema's value for later use:
return (values: Record<string, any>): FormErrors => {
try {
_schema.validateSync(values, { abortEarly: false, fullSchemaValue: values }); // I name it 'fullSchemaValue'
return {};
} catch (_yupError: any) {
const yupError: YupValidationResult = _yupError;
const results: any = {};
yupError.inner.forEach((error: YupError) => {
results[error.path.replaceAll('[', '.').replaceAll(']', '')] = error.message;
});
return results;
}
then, I make some custom yup.test function in my schema:
mySchemaAttribute: yup.string().test('testName1', 'This error message will show', function(value){ // didn't use arrow syntax to preserve 'this'.
const schemaValue: any = (this.options as any)?.fullSchemaValue; // the property I added that holds the schema value exists under 'this.options.[...]'
if(!schemaValue.topLevelObject.otherLayer.mySchemaAttribute && schemaValue.someOtherLocation.otherProp) {
return true
}
return false;
}),
I can surely make suite of helper functions and handle most cases this way, but it's kind of hacky feeling and verbose. Is there a better way that anyone's found?
I think in an ideal world we would be able to optionally append the full schema value in the actual yup code, and prop drill it down to be used in whatever grabs keys for the .when() function, but I haven't been using the library long enough to know if I've dug myself into an uneccessary rabbit hole.