jquense / yup

Dead simple Object schema validation
MIT License
22.9k stars 934 forks source link

How to require either one of two fields? (Cyclic dependency error) #79

Closed supermoos closed 7 years ago

supermoos commented 7 years ago

What (if possible) is the correct way to define that either the email or phone is a string > 1?

    var formModelSchema = yup.object({
        email: yup.string().email().when('phone', {
            is: (phone) => !phone || phone.length === 0,
            then: yup.string().email().required(),
            otherwise: yup.string()
        }),
        phone: yup.string().when('email', {
            is: (email) => !email || email.length === 0,
            then: yup.string().required(),
            otherwise: yup.string()
        })
    });

Uncaught (in promise) Error: Cyclic dependency: "phone"

jquense commented 7 years ago

Generally I move the validation up to the object. OR don't use when and write a custom test:

yup.string().test(function (value) {
  const { email } = this.parent;
  if (!email) return value != null
  return true
})

If you want to use when there is an escape hatch you can use, as documented in this test: https://github.com/jquense/yup/blob/master/test/object.js#L609

AndrewKvalheim commented 5 years ago

Correction to the above link:

https://github.com/jquense/yup/blob/masterstrong>@{2017-01-20}</strong/test/object.js#L609

dziugasmeskauskas commented 5 years ago

Generally I move the validation up to the object. OR don't use when and write a custom test:

yup.string().test(function (value) => {
  const { email } = this.parent;
  if (!email) return value != null
  return true
})

If you want to use when there is an escape hatch you can use, as documented in this test: https://github.com/jquense/yup/blob/master/test/object.js#L609

You have a typo in the code. You are declaring a function and using an arrow afterwards. Corrected:

 yup.string().test(function (value) {
   const { email } = this.parent;
   if (!email) return value != null
   return true
 })
Sletheren commented 4 years ago

Generally I move the validation up to the object. OR don't use when and write a custom test:

yup.string().test(function (value) => {
  const { email } = this.parent;
  if (!email) return value != null
  return true
})

If you want to use when there is an escape hatch you can use, as documented in this test: https://github.com/jquense/yup/blob/master/test/object.js#L609

If you're wondering why this is not working, then make sure you're not using an arrow function for the callback yup.string().test((value) => {.... won't work since this is undefined :)

GeoffreyHervet commented 4 years ago
    var formModelSchema = yup.object({
        email: yup.string().email().when('phone', {
            is: (phone) => !phone || phone.length === 0,
            then: yup.string().email().required(),
            otherwise: yup.string()
        }),
        phone: yup.string().when('email', {
            is: (email) => !email || email.length === 0,
            then: yup.string().required(),
            otherwise: yup.string()
        })
    },
   // This is what you missed
   [ [ 'email', 'phone' ] ]
);
Qwal commented 4 years ago

I had to use yup.object().shape({...}) with @GeoffreyHervet solution to avoid cyclic dependency error.

itminhnhut commented 3 years ago
    var formModelSchema = yup.object({
        email: yup.string().email().when('phone', {
            is: (phone) => !phone || phone.length === 0,
            then: yup.string().email().required(),
            otherwise: yup.string()
        }),
        phone: yup.string().when('email', {
            is: (email) => !email || email.length === 0,
            then: yup.string().required(),
            otherwise: yup.string()
        })
    },
   // This is what you missed
   [ [ 'email', 'phone' ] ]
);

error var validationSchemaFilter = Yup.object().shape( { bookingTimeBegin: Yup.string().when('bookingTimeEnd', { is: (bookingTimeEnd) => bookingTimeEnd?.length > 0, then: Yup.string().required('Chọn ngày bắt đầu'), otherwise: Yup.string(), }), bookingTimeEnd: Yup.string().when('bookingTimeBegin', { is: (bookingTimeBegin) => bookingTimeBegin?.length > 0, then: Yup.string().required('Chọn ngày kết thúc'), otherwise: Yup.string(), }), }, [['bookingTimeBegin', 'bookingTimeEnd']], );

loxosceles commented 2 years ago
    var formModelSchema = yup.object({
        email: yup.string().email().when('phone', {
            is: (phone) => !phone || phone.length === 0,
            then: yup.string().email().required(),
            otherwise: yup.string()
        }),
        phone: yup.string().when('email', {
            is: (email) => !email || email.length === 0,
            then: yup.string().required(),
            otherwise: yup.string()
        })
    },
   // This is what you missed
   [ [ 'email', 'phone' ] ]
);

Where is this documented? I would like to know how this works with properties of FieldArrays.

AlenJakob commented 1 year ago

Generally I move the validation up to the object. OR don't use when and write a custom test:

yup.string().test(function (value) {
  const { email } = this.parent;
  if (!email) return value != null
  return true
})

If you want to use when there is an escape hatch you can use, as documented in this test: https://github.com/jquense/yup/blob/master/test/object.ts

The file format has beend changed to .ts