score:1

Accepted answer

you can do like this way:

*I've done an example where at least one registrationNumber in array should be filled for your vehicles schema:

vehicles: Yup.array(
    Yup.object({
      registrationNumber: Yup.string(),
      make: Yup.string().required("make Required"),
    }).test(
      "registrationNumber test",
      // The error message that should appears if test failed
      "at least one registrationNumber should be filled",
      // Function that does the custom validation to this array
      validateAgainstPrevious
    )
  )

The function below its just an example. You can do your own logic here.

function validateAgainstPrevious() {
  // In this case, parent is the entire array
  const { parent } = this;
  
  // filtered array vechicles that doens't have registrationNumber
  const filteredArray = parent.filter((e) => !e.registrationNumber);
  
  // If length of vehicles that doesn't have registrationNumber is equals to vehicles  array length then return false;
  if (filteredArray.length === parent.length) return false;

  return true;
}

UPDATED

For the multiple error text issue, you can do a workaround:

Instead you pass TextField component to Field, like this:

<Field
   component={TextField}
   fullWidth={true}
   label="Registration Number"
   name={`vehicles[${index}].registrationNumber`}
/>

you can do this:

<Field
   // component={TextField}
   fullWidth={true}
   label="Registration Number"
   name={`vehicles[${index}].registrationNumber`}
   render={() => (
      <TextField
         error={Boolean(errors.vehicles)}
         helperText= {
            errors.vehicles && getVehiclesErrors(errors.vehicles)
         }
      />
   )}
/>

And created this function:

const getVehiclesErrors = (errors) => {
  return Array.isArray(errors)
    ? errors.filter((email, i, arr) => arr.indexOf(email) === i)
    : errors;
};

score:2

Instead Yup.object({}) use Yup.object().shape({ ... all the properties comes here})


Related Query

More Query from same tag