error message without submitting the form

Viewed 50

I am using yup for validations and everything is working fine. So it is like this:

    const HISTORY = useHistory();
    
      const [inputs, setInputs] = useState({
        Name: "",
        Surname: "",
      });
    
      const handleChange = (inputName) => (e) => {
        e.preventDefault();
    
        setInputs({
          ...inputs,
          [inputName]: e.target.value,
        });
      };
    
      const Continue = async (e) => {
        e.preventDefault();
        let formData = {
          Name: inputs.Name,
          Surname: inputs.Surname,
        };
    
        const isValid = await orderFormValidation.isValid(formData);
        if(isValid) {
          HISTORY.push({ pathname: "/checkout", state: inputs });
        }
      };
    
      return (
        <Form className="instantquote p-3 mb-5">
          <Form.Group controlId="formGroupFrom">
            <Form.Label className="form-subtitle">Name</Form.Label>
            <Form.Control
              type="text"
              placeholder="Name"
              name="Name"
              onChange={handleChange("Name")}
              defaultValue={inputs.Name}
            />
            {/* TODO: ERROR MESSAGE */}
          </Form.Group>
          

<Form.Group controlId="formGroupFrom">
            <Form.Label className="form-subtitle">Surname</Form.Label>
            <Form.Control
              type="text"
              placeholder="Surname"
              name="Surname"
              onChange={handleChange("Surname")}
              defaultValue={inputs.Surname}
            />
            {/* TODO: ERROR MESSAGE */}
          </Form.Group>
          <button className="btn button" onClick={Continue}>
            Details
            <BsArrowRightShort />
          </button>
        </Form>
      );

So basically, isValid is coming right. So for example, if one of the fields is empty, it returns false and it doesn't go to the next page which is checkout in our case. So my question is I want to give an error message but I dont know how to do it because I am not submitting the form. Here is my validation also:

export const orderFormValidation = yup.object().shape({
  Name: yup
    .string()
    .min(3, "Too Short!")
    .max(5, "Too Long!")
    .required("Name Required"),
Surname: yup
    .string()
    .min(3, "Too Short!")
    .max(5, "Too Long!")
    .required("Surname Required"),
});
1 Answers

you can add states to accept the error message like this:

 const HISTORY = useHistory();

  const [inputs, setInputs] = useState({
    Name: "",
    Surname: "",
  });
  const [name, setName] = useState("");
  const [surName, setSurName] = useState("");
  const handleChange = (inputName) => (e) => {
    e.preventDefault();

    setInputs({
      ...inputs,
      [inputName]: e.target.value,
    });
  };
  const nameValidation = yup.object().shape({
    Name: yup
      .string()
      .required("Name Required")
      .min(3, "Too Short!")
      .max(5, "Too Long!"),
  });
  const surNameValidation = yup.object().shape({
    Surname: yup
      .string()
      .required("Surname Required")
      .min(3, "Too Short!")
      .max(5, "Too Long!"),
  });
  const Continue = async (e) => {
    e.preventDefault();
    let formData = {
      Name: inputs.Name,
      Surname: inputs.Surname,
    };
    const isValidSurName = await surNameValidation.isValid(formData);
    const isValidName = await nameValidation.isValid(formData);
    if (isValidName) {
      setName("");
    } else {
      nameValidation.validate(formData).catch((ex) => {
        setName(ex.message);
      });
    }
    if (isValidSurName) {
      setSurName("");
    } else {
      surNameValidation.validate(formData).catch((ex) => {
        setSurName(ex.message);
      });
    }
    if (isValidName && isValidSurName) {
      HISTORY.push({ pathname: "/checkout", state: inputs });
    }
  };

  return (
    <Form className="instantquote p-3 mb-5">
      <Form.Group controlId="formGroupFrom">
        <Form.Label className="form-subtitle">Name</Form.Label>
        <Form.Control
          type="text"
          placeholder="Name"
          name="Name"
          onChange={handleChange("Name")}
          defaultValue={inputs.Name}
        />
        <p>{name}</p>
      </Form.Group>

      <Form.Group controlId="formGroupFrom">
        <Form.Label className="form-subtitle">Surname</Form.Label>
        <Form.Control
          type="text"
          placeholder="Surname"
          name="Surname"
          onChange={handleChange("Surname")}
          defaultValue={inputs.Surname}
        />
        <p>{surName}</p>
      </Form.Group>
      <button className="btn button" onClick={Continue}>
        Details
      </button>
    </Form>
  );

if you have more fields, you should extract the validations to a new component

Related