Search code examples
reactjsvalidationyup

React yup validation with and react-hook-form, array of different type of objects depends from one of object attribute


I have a form, where user can add with no limit ( add shareholder ).

Shareholder can be 2 different types ( NATURAL / LEGAL )

here is interface for thouse objects:

export interface shareholderNatural {
  type: 'NATURAL';
  firstName: string;
  lastName: string;
  personalCode: string;
  sharePart: number;
  politicallyExposed: boolean;
  country: string;
  position: string;
}

export interface shareholderLegal {
  type: 'LEGAL';
  companyName: string;
  companyCode: string;
  sharePart: number;
  politicallyExposed: boolean;
  country: string;
  position: string;
}

I need validation for: firstName, lastName, personalCode, sharePart if type is NATURAL companyName, companyCode, sharePart if type is NATURAL

Attribut type is set by the select from the component state when user click opn add another sharehoilder button (useState)

I tryed to do it with Yup.array().when( 'key', {})

 const validationSchema = Yup.object().shape({
shareholders: Yup.array().when('type', {
  is: 'NATURAL',
  then: Yup.array().of(
    Yup.object().shape({
      firstName: Yup.string().required(t('')),
      lastName: Yup.string().required(t('')),
      personalCode: Yup.string().required(t('')),
      sharePart: Yup.number().required(t('')),
    }),
  ),
  otherwise: Yup.array().of(
    Yup.object().shape({
      companyName: Yup.string().required(t('')),
      companyCode: Yup.string().required(t('')),
      sharePart: Yup.number().required(t('')),
    }),
  ),
}),

});

But in this case key attribute should be outside ...

Any help here ? Thank you.


Solution

  • You can check every field separately. Just replace type with needed field:

    const validationSchema = Yup.object().shape({
        shareholders: Yup.array().of(
          Yup.object().shape({
            firstName: Yup.string().when('type', {
              is: 'NATURAL',
              then: Yup.string().required(t(''))
            }),
            lastName: Yup.string().when('type', {
              is: 'NATURAL',
              then: Yup.string().required(t(''))
            }),
            personalCode: Yup.string().when('type', {
              is: 'NATURAL',
              then: Yup.string().required(t(''))
            }),
            sharePart: Yup.number().required(t('')),
            companyName: Yup.string().when('type', {
              is: 'LEGAL',
              then: Yup.string().required(t(''))
            }),
            companyCode: Yup.string().when('type', {
              is: 'LEGAL',
              then: Yup.string().required(t(''))
            }),
          })
        )
      )
    };