user101289
user101289

Reputation: 10422

Formik validation isSubmitting / isValidating not getting set to true

I've got a form that my users have requested I make it blindingly obvious that the form is invalid. So I'm planning to pop up a sweetalert dialog to let them know they need to double check the form. I thought I could do it in the validation like this to alert them when a submission attempt fails:

const validate = values => {
    console.log(formik.isSubmitting); // always prints false
    console.log(formik.isValidating); // always prints false
    const errors = {};
    if (!values.name) {
      errors.name = 'Required';
    }

    if (Object.keys(errors).length > 0 && formik.isSubmitting) {
        Swal.fire({
            icon: 'error',
            title: "Oops. . .",
            text: "There are errors with the form. Please double check your options.",
            footer: "<div>Problems: " + Object.keys(errors).join(', ') + "</div>"
        })
    }

    return errors;
};

const formik = useFormik({
    initialValues: {
        name: item.name
    },
    enableReinitialize: true,
    validate,
    onSubmit: values => {
       // also tried adding 
       formik.setSubmitting(true); 
       //do stuff
    }
})

but the isSubmitting / isValidating are always false. Do I need to pass in additional props to the validate function in order to access these values?

https://codesandbox.io/s/nervous-wescoff-cf2y1?file=/src/App.js

Upvotes: 4

Views: 5427

Answers (1)

ypahalajani
ypahalajani

Reputation: 800

I believe that the validate method would not be a good place to show the dialog box to the user. Your use case looks like a custom requirement for which the formik lib. shares what they do internally for form submission - https://formik.org/docs/guides/form-submission.

You could add a custom method for submission.

So, I've forked your sandbox and updated it - https://codesandbox.io/s/custom-form-submit-stackoverflow-8znzf

Let me know what you think.

Edit: Adding code so that even if the link gets expired, you may still know what to do

import React, { useState } from "react";
import "./styles.css";
import { useFormik } from "formik";
import Swal from "sweetalert2";
import "bootstrap/dist/css/bootstrap.min.css";

export default function App() {
  const [item, setItem] = useState({
    name: "",
    email: ""
  });

  const validate = (values) => {
    console.log("values: ", values);
    const errors = {};
    if (!values.name) {
      errors.name = "Required";
    }
    return errors;
  };

  const initialValues = {
    name: item.name,
    email: item.email
  };

  const formik = useFormik({
    initialValues,
    enableReinitialize: true,
    validate,
    onSubmit: (values) => {
      console.log("inside onSubmit", values);
    }
  });

  const customSubmitHandler = (event) => {
    event.preventDefault();
    const touched = Object.keys(initialValues).reduce((result, item) => {
      result[item] = true;
      return result;
    }, {});
    // Touch all fields without running validations
    formik.setTouched(touched, false);
    formik.setSubmitting(true);

    formik
      .validateForm()
      .then((formErrors) => {
        if (Object.keys(formErrors).length > 0) {
          Swal.fire({
            icon: "success",
            title: "Yes. . .",
            text: "This one should fire if everything is working right",
            footer:
              "<div>Problems: " + Object.keys(formErrors).join(", ") + "</div>"
          });
        } else {
          formik.handleSubmit(event);
        }
        formik.setSubmitting(false);
      })
      .catch((err) => {
        formik.setSubmitting(false);
      });
  };

  return (
    <form id="campaignForm" onSubmit={customSubmitHandler}>
      <div className="form-group">
        <label htmlFor="name">Name</label>
        <input
          id="name"
          type="text"
          onChange={formik.handleChange}
          value={formik.values.name}
          className="form-control"
          placeholder="Enter name"
        />
        {formik.errors.name ? (
          <div className="text-danger">{formik.errors.name}</div>
        ) : null}
      </div>
      <div className="form-group">
        <label htmlFor="name">Email</label>
        <input
          id="name"
          type="email"
          onChange={formik.handleChange}
          value={formik.values.email}
          className="form-control"
          placeholder="Enter email"
        />
        {formik.errors.email ? (
          <div className="text-danger">{formik.errors.email}</div>
        ) : null}
      </div>
      <div className="form-group">
        <button className="btn btn-info" type="submit">
          Submit
        </button>
      </div>
    </form>
  );
}

Upvotes: 3

Related Questions