skip to Main Content

I am trying to validate using formik and yup on react.js. In the schema I created for yup, there is an email and password section, I just want to show all the errors in the password section at the same time, the errors in the email section should be displayed in order, but I couldn’t do it, but I would be very grateful if you could help me.

Here is how I created the yup object

 const validationPageTwo = Yup.object({
   email: Yup.string().required("Required field"),
   password: Yup.string()
  .required("Required field password")
  .matches(/^(?=.{8,})/, "Must Contain 8 Characters")
  .matches(/^(?=.*[!@#$%^&*])/, " One Special Case Character")
  .matches(/^(?=.*[0-9])/, " One Number")
  .matches(/^(?=.*[a-z])/, " One Lowercase")
  .matches(/^(?=.*[A-Z])/, " One Uppercase"),
 });



const formik = useFormik({
 initialValues: {
  name: "",
  surname: "",
  email: "",
  password: "",
 },
 validationSchema: page === 1 ? validationPageOne : 
 validationPageTwo,
 onSubmit: (values) => {
  if (page === 1) {
    setPage(2);
  } else {
    alert(JSON.stringify(values));
  }
 },
});

2

Answers


  1. Chosen as BEST ANSWER

    Yes I finally solved the problem, if you want you can use it as a schema in formic and map all errors separately. Thanks to everyone who helped me solve the problem

    const validationPageTwo = Yup.object({
    email: Yup.string().required("Required field").email(),
    password: Yup.string()
      .required("Required field password")
      .test({
        test: (value) => {
          let errors = [];
    
          if (!/^(?=.{8,})/.test(value)) {
            errors.push("Must Contain 8 Characters");
          }
    
          if (!/^(?=.*[!@#$%^&*])/.test(value)) {
            errors.push("One Special Case Character");
          }
    
          if (!/^(?=.*[0-9])/.test(value)) {
            errors.push("One Number");
          }
    
          if (!/^(?=.*[a-z])/.test(value)) {
            errors.push("One Lowercase");
          }
    
          if (!/^(?=.*[A-Z])/.test(value)) {
            errors.push("One Uppercase");
          }
    
          if (errors.length > 0) {
            throw new Yup.ValidationError({
              errors: errors,
              inner: true,
              path: "password",
              message: errors,
              value: value,
              name: "ValidationError",
            });
          }
    
          return true;
        },
      }),
     });
    
    
    
    const formik = useFormik({
     initialValues: {
       email: "",
       password: "",
    },
    validationSchema:validationPageTwo,
    onSubmit: (values) => {
        alert(JSON.stringify(values));
    },
    });
    
    
    
     const { errors } = formik;
    
    console.log(errors.password);
    

  2. To show all the password errors at once, you could use the validate method instead of chaining multiple matches calls. This allows you to write a custom function where you can add your custom validation and add errors as you see fit.

    Here’s an example of how you could achieve it:

    const validationPageTwo = Yup.object({
      email: Yup.string().required("Required field"),
      password: Yup.string()
        .required("Required field password")
        .validate(value => {
          let errors = [];
    
          if (!/^(?=.{8,})/.test(value)) {
            errors.push("Must Contain 8 Characters");
          }
    
          if (!/^(?=.*[!@#$%^&*])/.test(value)) {
            errors.push("One Special Case Character");
          }
    
          if (!/^(?=.*[0-9])/.test(value)) {
            errors.push("One Number");
          }
    
          if (!/^(?=.*[a-z])/.test(value)) {
            errors.push("One Lowercase");
          }
    
          if (!/^(?=.*[A-Z])/.test(value)) {
            errors.push("One Uppercase");
          }
    
          if (errors.length > 0) {
            return new Yup.ValidationError(errors, value, 'password');
          }
    
          return value;
        }),
    });
    

    With the above schema, the password field will return all its errors at once as an array if the password value does not meet the requirements.

    In your form you can then list all the password errors by mapping through them, like:

    {
      errors.password && errors.password.inner.map((err, index) => <p key={index}>{err.message}</p>)
    }
    

    Remember to replace errors.password with the actual path to your password errors object in your form state.

    Just bear in mind that the validate function must either return the validated value (if validation succeeded), throw a Yup.ValidationError (if validation failed), or return a Promise that does either.

    Also, for email validation, you may want to add a rule to ensure that it is indeed an email:

    email: Yup.string()
        .required("Required field")
        .email("Must be a valid email address"),
    

    Please also note that with Formik + Yup, the errors from Yup are available in the errors prop that Formik provides to your form.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search