Reputation: 2490
I have defined a yup schema
export const ValidationSchema = yup.object().shape({
dateTo: yup
.date()
.required(MandatoryFieldMessage)
uebernachtungen: yup.array().of(
yup.object().shape({
ort: yup
.string()
.trim()
.max(100, Maximum100CharactersMessage)
.required(MandatoryFieldMessage),
bis: yup
.date()
.required(MandatoryFieldMessage)
.max(yup.ref("dateTo"), "display message") }))
})
I just want to use the value of dateTo
inside the array, so that all the bis
in the uebernachtungen
will not be allow do have a value greater than dateTo
.
The problem is that I can access items inside the array like ort
but I cannot access items out of it like dateTo
.
So in this case yup.ref("dateTo") will return undefined but yup.ref("ort")
will be correct. It seems that array has its own context and I cannot access to the parent context.
How would be this possible?
Upvotes: 6
Views: 15721
Reputation: 302
For some reason, the initial answer didn't work for me, but I did manage to find another solution using Yup.lazy
. Basically, just wrap everything around Yup.lazy
export const ValidationSchema = yup.lazy((globalContext) => yup.object().shape({
dateTo: yup
.date()
.required(MandatoryFieldMessage)
uebernachtungen: yup.array().of(
yup.object().shape({
ort: yup
.string()
.trim()
.max(100, Maximum100CharactersMessage)
.required(MandatoryFieldMessage),
bis: yup
.date()
.required(MandatoryFieldMessage)
.max(globalContext.dateTo, "display message") }))
}))
Upvotes: 0
Reputation: 492
Try this way, It worked fine for me.
import { array, date, object, string } from 'yup';
export const ValidationSchema = object().shape({
dateTo: date().required('MandatoryFieldMessage'),
uebernachtungen: array().when('dateTo', (dateTo, schema) =>
schema.of(
object().shape({
ort: string().trim().max(100, 'Maximum100CharactersMessage').required('MandatoryFieldMessage'),
bis: date().required('MandatoryFieldMessage').max(dateTo, 'display message')
})
)
)
});
Upvotes: 0
Reputation: 1674
Simply create a global variable dateToTmp
and assign value by test method:
check the line number 7
let dateToTmp;
const ValidationSchema = yup.object().shape({
dateTo: yup
.date()
.required(MandatoryFieldMessage)
.test('dateToTmp', 'assign value to variable', (value) => {
dateToTmp = value;
return true;
})
uebernachtungen: yup.array().of(
yup.object().shape({
ort: yup
.string()
.trim()
.max(100, Maximum100CharactersMessage)
.required(MandatoryFieldMessage),
bis: yup
.date()
.required(MandatoryFieldMessage)
.test('dateToCheck', 'display message', function (value) {
// access dateTo from passed context
return !(value > dateToTmp)
}))
})
Upvotes: -1
Reputation: 2463
I came through similar issue. I used this workthrough with success.
Idea: Pass whole form-data as a context to the schema and access any form value using
this.options.context
const ValidationSchema = yup.object().shape({
dateTo: yup
.date()
.required(MandatoryFieldMessage)
uebernachtungen: yup.array().of(
yup.object().shape({
ort: yup
.string()
.trim()
.max(100, Maximum100CharactersMessage)
.required(MandatoryFieldMessage),
bis: yup
.date()
.required(MandatoryFieldMessage)
.test('dateToCheck', 'display message', function (value) {
// access dateTo from passed context
if(value>this.options.context.dateTo) return false
return true }),
})) })
Passing Context
Without Formik
Send your Form data as a context while validating
ValidationSchema.validateSync(data, {context: form_data})
With Formik
Use validate instead of validationSchema
Pass your Form data as 4th argument in validateYupSchema which represents context and can be accessed later in schema.
Pass your schema as 2nd argument in validateYupSchema.
<Formik
validate={(value) => {
try {
validateYupSchema(value, ValidationSchema, true, value);
} catch (err) {
return yupToFormErrors(err); //for rendering validation errors
}
return {};
}}
onSubmit={} />
Upvotes: 5
Reputation: 9
Something like this could work, if i understood correctly ur question...
Example of using test to get value from yup scheme
Upvotes: 0