Reseting yup field based on another variable value #10382
-
Hi. First of all, great library. Thanks a lot for your hard work. Currently, I'm using RHF with yup. My yup object is static and is working fine right now. But I need to change some fields' rules based on some actions in my app. For example, I want to change the Max value of the Number field dynamically based on a variable's change which is not included in the form. I want to know if it is possible or not. and If yes, I'd appreciate any hints, guides, links, or code samples. Part of my yup schema: const schema = yup.object().shape({
ruleType: yup.string().required(errorMessages.required),
address: yup.string().required(errorMessages.required),
number: yup
.string()
.nullable()
.required(errorMessages.required)
.typeError(errorMessages.required)
.when(['ruleType'], {
is: (ruleType: string) => ruleType === 'collection',
then: yup
.string()
.nullable()
.test({
name: 'min',
exclusive: false,
params: {},
message: errorMessages.minNumber,
test: (value) => +value > 0,
}),
otherwise: yup
.string()
.nullable()
.test({
name: 'min',
exclusive: false,
params: {},
message: 'Must be more than 0',
test: (value) => +value > 0 + 10 ** -18,
}),
}),
}); As you can see, since the number field is a string, I have to turn it into a number and check whether it is more than zero or not. But sometimes a variable of type number gets changed inside of my code and I want to assign its value as the Max value to my number field. const methods = useForm({
defaultValues,
shouldFocusError: false,
resolver: yupResolver(schema),
}); And I have a state in my code that gets changed based on some actions: const [max, setMax] = useState(0); And then this max variable should be assigned as the max value of the number field inside the yup object(schema). Please consider that my yup object is much more complex than the one mentioned above and I'm also using a dynamic form (useFieldArray). Not sure whether I explained well and provided enough explanation or not. But If it's needed, I can provide a CodeSandBox. Thanks in advance. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
You can tap into the |
Beta Was this translation helpful? Give feedback.
-
I finally realized that I can use context which is one of the Step 1: Passing my variable as context to my yup validation schemaAs mentioned with the help of one of the // My State:
const [contextVariable, setContextVariable] = React.useState();
// useForm settings:
const methods = useForm<Type>({
defaultValues,
resolver: yupResolver(validationSchema),
context: {
contextVariable, // Pass my variable to yup schema
},
}); Step2: Update yup version:I was not using the latest yup version. So with the help of the migration guide, I managed to use the latest version and its new features. Step3: Accessing the passed variable inside yup schema:You can access any passed context variable inside the yup schema by using one of the Schema.test(name: string, message: string | function | any, test: function): Schema OR Schema.test(name: string, message: string | function | any, test: function): Schema functions that yup provides: Using const validationSchema = yup.object().shape({
field1: yup.string(),
field2: yup
.string()
.when(
['field1', '$contextVariable'], // Notice the $ sign!!!
([field1, contextVariable], schema) => {
console.log(field1, contextVariable);
// And do your logic here with the available variables
return schema.required(); // Or more complex rules
}
),
}); Using const validationSchema = yup.object().shape({
field1: yup.string(),
field2: yup
.string()
.test(
'name',
'message',
// Must not be an arrow function in order to access this.options.context because yup binds to "this".
function test(value, {path}) {
const { contextVariable } = this.options.context;
// And do your logic with the accessed variable context
return true;
}
),
}); |
Beta Was this translation helpful? Give feedback.
I finally realized that I can use context which is one of the
useForm
's Schema validation props. These are the steps that I took to get the code to work in the way I wanted:Step 1: Passing my variable as context to my yup validation schema
As mentioned with the help of one of the
useForm's
schema validation props called context, I managed to pass my state to yup schema like below: (code is super simplified)Step2: Update yup version: