首页 > 解决方案 > 如何在使用 yup 验证对象模式时出现第一个错误

问题描述

我正在使用 Yup 根据验证模式验证嵌套数据对象。我想检索第一个验证错误的路径。我用validate()试过了。它具有abortEarly默认为 true 的选项。所以在这种情况下,应该返回第一个错误。

但是,我总是得到最后一个错误。我不确定我错过了什么。

以下是我迄今为止尝试过的代码。

  const validationSchema = Yup.object().shape({
    basicDetails: Yup.object().shape({
      firstName: Yup.string().required("Required first name"),
      lastName: Yup.string().required("Required last name"),
      gender: Yup.string().required("Required gender"),
      phoneNumber: Yup.string().required("Required phone number"),
      emailId: Yup.string().required("Email id is required")
    }),
    educationDetails: Yup.object().shape({
      graduationDegree: Yup.string().required("Required graduation degree"),
      postGraduationDegree: Yup.string().required(
        "Required post graduation degree"
      ),
      registrationNumber: Yup.string().required("Required registration number"),
      workExperience: Yup.string().required("Required work experience")
    })
  });

  const dataObject = {
    basicDetails: {
      firstName: "Nik",
      lastName: "Test",
      gender: "male",
      phoneNumber: "9876543210",
      emailId: ""
    },
    educationDetails: {
      graduationDegree: "Degree 1",
      postGraduationDegree: "Postgraduation Degree 1",
      registrationNumber: "",
      workExperience: ""
    }
  };

  const validateSchema = async () => {
    const validationResult = await validationSchema
      .validate(dataObject)
      .catch((err) => {
        return err;
      });
    // this returns last error. however, as per the documentation, it should return the first error.
    console.log(validationResult.errors, validationResult.params);

    const validationResult1 = await validationSchema
      .validate(dataObject, { abortEarly: false })
      .catch((err) => {
        return err;
      });
    // this returns array of all errors in correct order.
    console.log(validationResult1.errors);
  };


是最小示例的代码沙箱链接。

我也尝试了简单的模式,但得到了相同的结果。

标签: reactjsyup

解决方案


我认为您需要验证abortEarly: false然后使用第一个错误。原因是,abortEarly没有做我们认为它会做的事情。一旦发现一个错误,它就不会停止进一步的验证。由于验证是按架构级别并行运行的。

因此,我认为这就是你需要做的或多或少的事情:

  const validateNestedSchema = async () => {
    const validationResult = await validationSchemaNested
      .validate(dataObjectNested, { abortEarly: false })
      .catch((err) => {
        return err;
      });
    console.log(validationResult.inner[0].path); // gives "basicDetails.emailId" 
  };

分叉的沙箱,如果需要的话


FWIW,他们似乎正在讨论此问题中的验证链选项,但似乎还没有结论/实施。


推荐阅读