How to add error message to yup validation for array containing distinct values in FieldArray?

Viewed 1858

I am trying to add Error message for my Field Array which should contain array of distinct elements. Below is my validation:

export const emails = yup
  .array(
    yup
      .string()
      .matches(/^\S+@\S+$/, {
        message: "Must be a valid email id"
      })
  )
  .test("Unique", "Email ids need to be unique", values => {
    return new Set(values).size === values.length;
  });

And here is the ErrorMessage component inside my FieldArray component's render prop:

render={({ form, push, remove }) => (
          <div>
            {range(0, form.values[name].length).map(i => (
              <div className={styles.inputContainer} key={i}>
                <div>
                  <InputComponent name={`${name}.${i}`} {...props} />
                  <Button color="danger" onClick={() => remove(i)}>
                    <FaTimes />
                  </Button>
                </div>
                <ErrorMessage
                  name={`${name}.${i}`}
                  render={msg => (
                    <FormFeedback style={{ display: "block" }}>
                      {msg}
                    </FormFeedback>
                  )}
                />
              </div>
            ))}
            <Button
              color="info"
              onClick={() => push("")}
              disabled={disabled || form.values[name].slice(-1)[0] === ""}
            >
              <FaPlus />
            </Button>
          </div>
        )}

However I get the error message as shown below. The message comes as one by one letter. I understand because I am including it in my range render method. But I have included the Error message component inside, because I want to show the error for invalid email ids as well. enter image description here

1 Answers

I, with help of someone figured out the solution. Let me jot it down if anybody needs it.

Basically, the Error message component prints out any error messages generated. It is not able to distinguish between where and what from the error messages.

So, I made use of of form attribute from render props of FieldArray component. The error message comes as a property of form as form.errors. However the key to distinguish between the two ErrorMessage components is that the inner form.errors comes as an array and the outer one comes as a string. So the solution is to check the datatype of form.errors object. Below is the code snippet.

render={({ form, push, remove }) => (
          <div>
            {range(0, form.values[name].length).map(i => {
              return (
                <div className={styles.inputContainer} key={i}>
                  <div>
                    <InputComponent name={`${name}.${i}`} {...props} />
                    <Button color="danger" onClick={() => remove(i)}>
                      <FaTimes />
                    </Button>
                  </div>
                  {typeof form.errors[name] !== "string" && (
                    <ErrorMessage
                      name={`${name}.${i}`}
                      render={msg => {
                        return (
                          <FormFeedback style={{ display: "block" }}>
                            {msg}
                          </FormFeedback>
                        );
                      }}
                    />
                  )}
                </div>
              );
            })}
            {typeof form.errors[name] === "string" && (
              <ErrorMessage
                name={`${name}`}
                render={msg => (
                  <FormFeedback style={{ display: "block" }}>
                    {msg}
                  </FormFeedback>
                )}
              />
            )}
Related