Home > Back-end >  Formik conditional validation does not work
Formik conditional validation does not work

Time:09-14

I have form with few inputs. One of them is file input, numbers of file inputs is dynamic:

<EuiFilePicker
 id={`templateFiles.${index}.documentTemplate`}
 name={`templateFiles.${index}.documentTemplate`}
 display="default"                                
 accept=".ftl"
 onChange={event => {setFieldValue(`templateFiles.${index}.documentTemplate`,event[0])}}
/>

I am trying to make files required only if one of previous input (contactType) is specific value (LETTER). I have something like this:

<EuiSelect
 options={Object.values(ContactType)}
 id={'contactType'}
 name={'contactType'}
 label={t('pages.participant.communicate.columns.contactType')}
/>

Where:

export enum ContactType {
  LETTER = 'LETTER',
  CALL = 'CALL',
}

And validationSchema:

export const projectContactSchema: SchemaOf<ProjectContactDto> = Yup.object().shape({

 {other values...}

  contactType: Yup.mixed()
    .oneOf(Object.values(ContactType))
    .required(i18next.t('pages.participant.communicate.inputs.contactTypeRequired')),

  templateFiles: Yup.array()
    .of(
      Yup.object().shape({
        language: Yup.mixed()
          .oneOf(Object.values(eLanguage))
          .required(i18next.t('pages.participant.communicate.inputs.languageRequired')),
        documentTemplate: Yup.mixed().when('contactType', {
          is: contactType => contactType === 'LETTER',
          then: Yup.mixed().required(i18next.t('pages.participant.communicate.inputs.templateFileRequired')),
          otherwise: Yup.mixed().notRequired(),
        }),
      })
    )
    .unique('Languages should be unique', (val: any) => val.language)
    .notRequired()
    .nullable(),
})

But this just does not work. Files are not required even if contactType is selected as a LETTER. I was trying other syntax like :

is: 'LETTER',
then: ... 

But result is the same.

CodePudding user response:

I just found a solution, i moved 'when' statement two steps higher. Seems that yup can't check condition if its nested.

templateFiles: Yup.array()
    .when('contactType', {
      is: contactType => contactType === 'LETTER',
      then: Yup.array().of(
        Yup.object().shape({
          language: Yup.mixed()
            .oneOf(Object.values(eLanguage))
            .required(i18next.t('pages.participant.communicate.inputs.languageRequired')),
          documentTemplate: Yup.mixed().required('test'),
        })
      ),
      otherwise: Yup.array().of(
        Yup.object().shape({
          language: Yup.mixed()
            .oneOf(Object.values(eLanguage))
            .required(i18next.t('pages.participant.communicate.inputs.languageRequired')),
          documentTemplate: Yup.mixed().notRequired(),
        })
      ),
    })
  • Related