Yup: is it possible to have nested .whens()?

Created on 8 Oct 2018  路  8Comments  路  Source: jquense/yup

I'm trying to achieve nested .when() calls, but with no success.

I'm trying something similiar to the following example:

const schema = Yup.object().shape({
  day: Yup.number(),
  month: Yup.number(),
  year: Yup.number().when("day", {
    is: 1,
    then: Yup.number.when("month", {
      is: 1,
      then: Yup.number().required("Its january, please select the year"),
      otherwise: Yup.number().required(
        "Its not january, please select the year"
      )
    }),
    otherwise: Yup.number()
  })
});

Does anyone have an idea of how can I achieve that?

Most helpful comment

Nested whens don't work unfortunately, but you can flatten them by doing a when for multiple keys at once

when(['day', 'month'], { is: (day, month) => true, ... })

All 8 comments

Nested whens don't work unfortunately, but you can flatten them by doing a when for multiple keys at once

when(['day', 'month'], { is: (day, month) => true, ... })

Hi, @jquense. Is it possible at all? And how it could be achieved?

I mean, nestingwhens, not combining them, which is not good in a matter of reusabilty and testabilty of switchers like below.

 passport: yup.string().whenLawful(
    schema => schema.passport().whenServicesSelected(
      passportSchema => passportSchema.required('Passport is required'),
      passportSchema => passportSchema.notRequired(),
    ),
    schema => schema.notRequired(),
  ),

@ugeng at the moment no there isn't any support for it. There isn't a strong reason why, but it's complicated enough that it's not super simple to add. I'm happy to evaluate a PR tho if someone is up for it.

Well, I suppose, strong reasons are purity, readability and testability of code...
I wish I have more free time for that...
At the moment, conditional logic in my schemes is not way too complicated (and I really can "flatten" predicates seamlessly), but when it does I would gladly (or sadly) dive deeper in this feature..
Thanks.

While this doesn鈥檛 exist yet, have anyone found a workaround or would have a suggestion on how do deal with a validation like the following?

const schematic = Yup.object().shape({
    aBoolean: Yup.boolean(),
    aThing: Yup.object().when("aBoolean", {
           is: true,
           then: Yup.object().shape({
                 aString: Yup.string(),
                 anotherString: Yup.string().when("aString", {
                        is: "theRightThing",
                        then: Yup.string().required()
                  })
           }).required()        
    })
})

@jquense any plans to support nested whens?

As of quarantine 2020, this now works as you think it should:

lastDancingDay: Yup.string().when('myDance', {
    is: true,
    then: Yup.string().when('doYouTango', {
        is: 'Yes',
        then: Yup.string().required('Dancing shoes required'),
    }),
}),

I think the .nullable() is still not handled in nested "whens"

Was this page helpful?
0 / 5 - 0 ratings