RayMan
RayMan

Reputation: 133

Error: Cyclic dependency with Yup Validation

I have this Yup validation schema that includes a check on a min_amount and max_amount value. I'm using it on a ReactJS Form.

const amountsSchema = yup.object({
  min_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('min_amount must be a number')
    .when('max_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().lessThan(yup.ref('max_amount'), 'min_amount must be less than maximum amount'),
    })
    .required(),

  max_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('max_amount must be a number')
    .when('min_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().moreThan(yup.ref('min_amount'), 'max_amount must be greater than minimum amount'),
    })
    .required(),
});

The problem is that it raises this error:

Error: Cyclic dependency, node was:"max_amount"

How do I write the schema correctly so that whichever field the user fills in first/last, the schema will correctly compare the two fields as the user fills the form? What inspired me to write it this way is that before when it was like this:

const amountsSchema = yup.object({
  min_amount: yup.number()
    .min(1)
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('min_amount must be a number')
    .required(),

  max_amount: yup.number()
    .min(1)
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('max_amount must be a number')
    .moreThan(yup.ref('min_amount'), 'max_amount must be greater than minimum amount')
    .required(),
});

a user could fill in the max_amount first and then fill in a larger min_amount and bypass the validation.

Upvotes: 10

Views: 23885

Answers (1)

tuvudu
tuvudu

Reputation: 177

I think you can try

const amountsSchema = yup.object().shape({
  min_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('min_amount must be a number')
    .when('max_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().lessThan(yup.ref('max_amount'), 'min_amount must be less than maximum amount'),
    })
    .required(),

  max_amount: yup.number()
    .max(999999999999999)
    .nullable()
    .transform((v, o) => (o === '' ? null : v))
    .typeError('max_amount must be a number')
    .when('min_amount', {
      is: '',
      then: yup.number().min(1),
      otherwise: yup.number().moreThan(yup.ref('min_amount'), 'max_amount must be greater than minimum amount'),
    })
    .required(),
}, ['max_amount', 'min_amount']);

Upvotes: 16

Related Questions