Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

javascript - Yup when condition inside nested object

so i have a problem with conditional validation using yup. Basically i want shipping to have required properties when the checkbox is not toggled. I am using yup's when feature and i can't figure out how to reference the sameShippingAsBilling boolean value from that shipping nested object.

When checkbox is false, everything is working fine, errors are shown... But when checkbox is checked, i get this error: "Cannot use 'in' operator to search for 'default' in undefined"

The problem is that the value in is callback is undefined. Is it even possible to access the outer variables in when from those nested objects or not. What is the alternative way to do this?

Here is the sandbox example

const schema = Yup.object({
  sameShippingAsBilling: Yup.bool(),
  billing: Yup.object({
    line1: Yup.string().required(),
    city: Yup.string().required(),
    country: Yup.string().required()
  }),
  shipping: Yup.object({
    line1: Yup.string().when("sameShippingAsBilling", {
      is: !val || val === false,
      then: Yup.string().required(),
    }),
    city: Yup.string().when("sameShippingAsBilling", {
      is: !val || val === false,
      then: Yup.string().required(),
    }),
    country: Yup.string().when("sameShippingAsBilling", {
      is: !val || val === false,
      then: Yup.string().required(),
    })
  })
});

const addrValues = { line1: "", city: "", country: "" };

const formOpts = {
  mode: "onChange",
  reValidateMode: "onChange",
  defaultValues: {
    sameShippingAsBilling: true,
    billing: { ...addrValues },
    shipping: { ...addrValues }
  },
  resolver: yupResolver(schema)
};

export default function CheckoutForm() {
  const methods = useForm(formOpts);
  const { watch } = methods;

  const shippingAsBilling = watch("sameShippingAsBilling");

  const onSubmit = async (data) => {
    console.log(data);
  };

  return (
    <MuiThemeProvider theme={createMuiTheme()}>
      <FormProvider {...methods}>
        <form onSubmit={methods.handleSubmit(onSubmit)} noValidate>
          <pre>errors: {JSON.stringify(methods.errors, null, 2)}</pre>

          <div className="group">
            <FormTextField name="billing.line1" />
            <FormTextField name="billing.city" />
            <FormTextField name="billing.country" />
          </div>

          <div>
            <FormCheckbox name="sameShippingAsBilling" />
          </div>

          {!shippingAsBilling && (
            <div className="group">
              <FormTextField name="shipping.line1" />
              <FormTextField name="shipping.city" />
              <FormTextField name="shipping.country" />
            </div>
          )}

          <div>
            <button type="submit">Pay</button>
          </div>
        </form>
      </FormProvider>
    </MuiThemeProvider>
  );
}
question from:https://stackoverflow.com/questions/65848669/yup-when-condition-inside-nested-object

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Hm, i added .nullable().default(null) to shipping and apparently it works. technically still don't have access to boolean true/false, it works because val is undefined and it adds that required condition... For a temp solution it is fine, and i don't have to fiddle with .test() or other strange solutions. And i don't even care at this point when a library that calls it self "dead simple object schema validation", and yet i waste time on these simple things.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...