yup: Nested object validation with when not working properly.
When i’m trying to validate a nested object. within when, it is not validating the request properly.
const updateRecord = Yup.object().shape({
title: Yup.string()
.required()
.label("Post title"),
description: Yup.string()
.required()
.label("Post description"),
is_update: Yup.boolean()
.default(false)
.required(),
images: Yup.object().shape({
logoImage: Yup.mixed().when("is_update", {
is: true,
then: Yup.mixed()
.nullable()
.test("fileFormat", "Only .png file allowed.", value => {
if (!value) {
return true;
}
return value && ["image/png"].includes(value.type);
})
.label("Logo image"),
otherwise: Yup.mixed()
.required()
.test("fileFormat", "Only .png file allowed.", value => {
if (!value) {
return true;
}
return value && ["image/png"].includes(value.type);
})
.label("Logo image")
}),
backgroundImage: Yup.mixed().when("is_update", {
is: true,
then: Yup.mixed()
.nullable()
.test("fileFormat", "Only .png file allowed.", value => {
if (!value) {
return true;
}
return value && ["image/png"].includes(value.type);
})
.label("Background image"),
otherwise: Yup.mixed()
.required()
.test("fileFormat", "Only .png file allowed.", value => {
if (!value) {
return true;
}
return value && ["image/png"].includes(value.type);
})
.label("Background image")
})
})
});
Here i’m validating form based on is_update key which can be either true or false. but I’m getting it undefined. i have tried to console using this.
is: value => {
console.log(value);
return true;
}
It is logging is_update as undefined.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 33
- Comments: 17 (4 by maintainers)
Those who encountered this issue, check
from
.A workaround I found is to use
Yup.mixed.test()
Example
Also, good to note that instead of
false
you can returnthis.createError({ message: "YourCustomErrorMessage" });
if you have different failures in the test.At a minimum could you please document
context.from
?I’m having to do
and I really wish I knew exactly why it worked.
Well, this was the best solution i could find, but it has a problem with Typescript:
Unsafe assignment of an
anyvalue.
andUnsafe member access [1] on an
anyvalue.
.Adding $ to field names gives no result. I need to access to the field in the root of my schema, is there a way to have it?
@akmjenkins I already have tried your solution. but the thing is that value is coming as undefined only if i’m doing it in nested object. if i’ll compare it in parent object, everything works fine.
@Jule- Set the context to the value being validated and you can use
$switchValue
@akmjenkins thanks for the response! I think I can make a workaround with this indeed. But I’ll need to wrap my schema before giving it to Formik which works directly with yup schema for validation out of the box (so normally I do not call validate myself).
It feels a little wonky though to give artificially the context side by side of the same actual “context” being validated (the first argument) while you define conditional validation directly in your schema.
Hope to see a smoother alternative in the future! 🙂 Thanks again for your time and good work! 😉 👍
@akmjenkins thanks for the quick response! 🙂 Unfortunately my explanation was a little misleading… By “context” I wanted to mean the upper schema full data object that we are validating. Maybe I am wrong but I can’t access upper schema properties with
$
notation, right?Here is my minimum repro use case:
What I would like to have is
switchValue
added somehow to the context or closure in order to achieve my validation. The solution I was suggesting in my previous comment was something like that (taking the.test()
method approach):ValidateContext
being a new interface/type or something already existing, I do not know what is available under the hood.Is that possible?
Thanks!