Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test for uniqueness of value in Yup.array?

I have form with dynamic amount of inputs (admin email) however checking for uniqueness fails:

      validationSchema={Yup.object().shape({
        adminEmails: Yup.array()
          .of(
            Yup.string()
              .notOneOf(Yup.ref('adminEmails'), 'E-mail is already used')

What is best approach here? FYI, as a form helper I use Formik.

like image 620
IProblemFactory Avatar asked Jan 08 '19 14:01

IProblemFactory


2 Answers

Simply Do This It works for me

First Define this function in your react component

    Yup.addMethod(Yup.array, "unique", function (message, mapper = (a) => a) {
    return this.test("unique", message, function (list) {
      return list.length === new Set(list.map(mapper)).size
    })
  })

Just Put this schema inside your Formik tag

<Formik
    initialValues={{
      hotelName: "",
      hotelEmail: [""],
    }}
    validationSchema={Yup.object().shape({
      hotelName: Yup.string().required("Please enter hotel name"),
      hotelEmail: Yup.array()
        .of(
          Yup.object().shape({
            email: Yup.string()
              .email("Invalid email")
              .required("Please enter email"),
          }),
        )
        .unique("duplicate email", (a) => a.email),
    })}
    onSubmit={(values, { validate }) => {
      getFormPostData(values)
    }}
    render={({ values, errors, touched }) => (
      <Form>
            <FieldArray
                  name="hotelEmail"
                  render={(arrayHelpers) => (
                    <>
                      {values.hotelEmail.map((hotel, index) => (
                        <div class="row" key={index}>
                          <div className="col-md-8 mt-3">
                            <div className="user-title-info user-details">
                              <div className="form-group d-flex align-items-center mb-md-4 mb-3">
                                <label className="mb-0" htmlFor="hotelName">
                                  {lang("Hotelmanagement.hotelsystemadmin")}
                                  <sup className="text-danger">*</sup>
                                </label>
                                <div className="w-100">
                                  <Field
                                    name={`hotelEmail.${index}.email`}
                                    className="form-control"
                                    id="hotelEmail"
                                    placeholder={lang(
                                      "Hotelmanagement.hotelsystemadmin",
                                    )}
                                  />
                                  <span className="text-danger d-block">
                                    {errors &&
                                      errors.hotelEmail &&
                                      errors.hotelEmail[index] &&
                                      errors.hotelEmail[index].email && (
                                        <span className="text-danger d-block">
                                          {errors.hotelEmail[index].email}
                                        </span>
                                      )}
                                      {errors &&
                                      errors.hotelEmail &&(
                                        <span className="text-danger d-block">
                                          {errors.hotelEmail}
                                        </span>
                                      )}
                                  </span>
                                </div>
                              </div>
                            </div>
                          </div>
                          <div className="col-md-2 mt-3">
                            {index > 0 && (
                              <i
                                className="bx bx-minus addnewBtn "
                                onClick={() => arrayHelpers.remove(index)}
                              />
                            )}
                            {index === values.hotelEmail.length - 1 && (
                              <i
                                className="bx bx-plus addnewBtn ml-5"
                                onClick={() => arrayHelpers.push("")}
                              />
                            )}
                          </div>
                        </div>
                      ))}
                    </>
                  )}
                />



 

not to show error do this following

 {errors &&
   errors.hotelEmail &&(
      <span className="text-danger d-block">
            {errors.hotelEmail}
      </span>
 )}
)} />
like image 87
Krishna Jangid Avatar answered Oct 12 '22 11:10

Krishna Jangid


Try this:

Yup.addMethod(Yup.array, 'unique', function(message, mapper = a => a) {
    return this.test('unique', message, function(list) {
        return list.length  === new Set(list.map(mapper)).size;
    });
});

Then use it like this:

const headersSchema = Yup.object().shape({
    adminEmails: Yup.array().of(
        Yup.string()
    )
    .unique('email must be unique')
})
like image 37
olefrank Avatar answered Oct 12 '22 13:10

olefrank