Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yup array validation for each field in an array #952

Closed
devevignesh opened this issue Jun 26, 2020 · 3 comments
Closed

Yup array validation for each field in an array #952

devevignesh opened this issue Jun 26, 2020 · 3 comments

Comments

@devevignesh
Copy link

I want to validate each field in an array of objects.

For example: I have 5 objects in an array "invitees". I want to validate only if inner constraints are satisfied

const validationSchema = Yup.object().shape({
  invitees: Yup.array().of(
    Yup.object().shape(
      {
        first_name: Yup.string().when(["email_id", "related_as"], {
          is: (email_id, related_as) => email_id || related_as,
          then: Yup.string().required("Enter first name"),
        }),
        email_id: Yup.string()
          .email("Enter a valid email")
          .when(["first_name", "related_as"], {
            is: (first_name, related_as) => first_name || related_as,
            then: Yup.string().required("Enter an email"),
          }),
        related_as: Yup.string().when(["first_name", "email_id"], {
          is: (first_name, email_id) => first_name || email_id,
          then: Yup.string().required("Select role"),
        }),
      },
      [
        ["first_name", "email_id"],
        ["first_name", "related_as"],
        ["email_id", "related_as"],
      ]
    )
  ),
});
@jquense
Copy link
Owner

jquense commented Jun 26, 2020

not really sure what you are asking for here. You can define whatever test you'd like on the array

@devevignesh
Copy link
Author

devevignesh commented Jun 29, 2020

I want to make sure user has entered the values for all the fields on formik form submit. I have added a validation schema to test duplicate email and validate each row fields both are working as expected

My question: I need to add one more test to validate the form fields has values ONLY on form submit. But if I add test after unique it is not working

Initial values:

"initialValues": {
    "invitees": [
      {
        "name": "",
        "first_name": "",
        "last_name": "last name",
        "email_id": "",
        "related_as": "Manager"
      },
      {
        "name": "name",
        "first_name": "",
        "last_name": "last name",
        "email_id": ""
      },
      {
        "name": "name",
        "first_name": "",
        "last_name": "last name",
        "email_id": ""
      },
      {
        "name": "name",
        "first_name": "",
        "last_name": "last name",
        "email_id": ""
      },
      {
        "name": "name",
        "first_name": "",
        "last_name": "last name",
        "email_id": ""
      }
    ]
  }
Yup.addMethod(Yup.array, "unique", (message, path) => {
  return this.test("unique", (lists) => {
    const uniqArray = _.uniqBy(lists, path),
      mapper = (x) => _.get(x, path),
      set = [...new Set(lists.map(mapper))];
    if (uniqArray.length !== lists.length) {
      const idx = _.findIndex(lists, (list, i) => mapper(list) !== set[i]);
      if (idx !== -1) {
        return this.createError({ path: `invitees[${idx}].${path}`, message });
      }
    }
    return true;
  });
});

const validationSchema = Yup.object().shape({
  invitees: Yup.array()
    .of(
      Yup.object().shape(
        {
          first_name: Yup.string().when(["email_id", "related_as"], {
            is: (email_id, related_as) => email_id || related_as,
            then: Yup.string().required("Enter first name"),
          }),
          email_id: Yup.string()
            .email("Enter a valid email")
            .when(["first_name", "related_as"], {
              is: (first_name, related_as) => first_name || related_as,
              then: Yup.string().required("Enter an email"),
            }),
          related_as: Yup.string().when(["first_name", "email_id"], {
            is: (first_name, email_id) => first_name || email_id,
            then: Yup.string().required("Select role"),
          }),
        },
        [
          ["first_name", "email_id"],
          ["first_name", "related_as"],
          ["email_id", "related_as"],
        ]
      )
    )
    .unique("Duplicate email", "email_id")
    .test("something") -> **not working**
    .required("Must have invitees")
    .min(5, "Minimum of 5 invitees"),
});

@jquense
Copy link
Owner

jquense commented Jun 30, 2020

yup has no concept of "on form submit" so it'd be hard to run a test only when that happens without using something like yup's context to pass in a value indicating that it's submitting.

I'm still not really sure what you are after, follow the issue template and provide a runnable example of a failing test that you expect to work otherwise it's not super clear waht behavior you expect and how your case differs from it, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants