I am trying to write a custom yup util for my project. my goal here is to make the form fields specified according to the data coming from the backend service conform to a single type or rule (eg. key-value for selectBox). For some reason, the validation I have written for the data sent by the backend in the code I wrote does not work :), it actually freezes as a yup object and the describe method also works, but it does not validate with the value values I give, I have tried different solution methods to solve the problem, but I have not been able to solve the problem. I would like help from you on this issue, if there is something wrong with my code or if you have any ideas, I would be very grateful, thank you in advance.
import * as yup from 'yup';
const defaultValidationRules = (customMessage) => {
return {
string: yup
.string()
.min(1)
.required(customMessage ?? `path is required`),
number: yup.number().required(customMessage ?? `path is required`),
boolean: yup.boolean().required(customMessage ?? `path is required`),
object: yup.object().required(customMessage ?? `path is required`),
array: yup.array().required(customMessage ?? `path is required`)
};
};
const createValidationSchema = (backendDependencies) => {
const shape = {};
if (Array.isArray(backendDependencies)) {
backendDependencies.forEach((dependency) => {
const { path, data, rule, customRule, customMessage, objectPathField } = dependency;
const subShape = {};
if (Array.isArray(data)) {
data.forEach((item) => {
if (customRule) {
subShape[item[objectPathField]] = customRule;
} else {
subShape[item[objectPathField]] = defaultValidationRules(customMessage)[rule];
}
});
} else {
Object.keys(data).forEach((item) => {
if (customRule) {
subShape[item] = customRule;
} else {
subShape[item] = defaultValidationRules(customMessage)[rule];
}
});
}
shape[path] = yup.object().shape(subShape);
});
} else {
const { path, data, rule, customRule, customMessage, objectPathField } = backendDependencies;
const subShape = {};
if (Array.isArray(data)) {
data.forEach((item) => {
if (customRule) {
subShape[item[objectPathField]] = customRule;
} else {
subShape[item[objectPathField]] = defaultValidationRules(customMessage)[rule];
}
});
} else {
Object.keys(data).forEach((item) => {
if (customRule) {
subShape[item] = customRule;
} else {
subShape[item] = defaultValidationRules(customMessage)[rule];
}
});
}
if (!shape[path]) {
shape[path] = yup.object().shape(subShape);
}
}
return yup.object(shape);
};
const validateForm = async (values, backendDependencies, valuesSchema, setErrors) => {
const backendSchema = createValidationSchema(backendDependencies);
console.log('backendSchema: ', backendSchema.describe());
console.log('values: ', values);
try {
await valuesSchema.validate(values, { abortEarly: false });
await backendSchema.validate(values, { abortEarly: false });
return null;
} catch (err) {
const errors = {};
if (err.inner) {
err.inner.forEach((error) => {
errors[error.path] = error.message;
});
}
setErrors(errors);
return errors;
}
};
export default validateForm;
The code I have written is as above and you can see the following example for usage example
validateForm(
values,
{
path: 'lawControlClauses',
data: controlClauses,
rule: 'boolean',
objectPathField: 'value'
},
legalUnitReviewNewSchema,
formikLegalUnitReview.setErrors
);