Home > Blockchain >  How do I set initialValues of useFormik to data returned from an API request
How do I set initialValues of useFormik to data returned from an API request

Time:02-12

I have an update ProfilePage component and I want to preload the form values with the data received from an Axios API request using useQuery, but it seems the useFormik initialValues render before the request is completed therefore having the initial values to be undefined, can anyone help me ?

  const { isSuccess, data } = useQuery("author", async () => {
    const endPoint = `${baseURL}/auth/author`;
    return Axios.get(endPoint, {
      headers: {
        "x-auth-token": token,
      },
    })
      .then(({ data }) => {
        return data.author;
      })
      .catch((err) => {
        setErrors(err.response.data.errors[0].msg);
        console.log(errors);
      });
  });

  const formik = useFormik({
    initialValues: {
      firstname: data.firstname,
      lastname: data.lastname,
      gender: data.gender,
      dob: data.dob,
      email: data.email,
      oldPassword: "",
      newPassword: "",
      confirmNewPassword: "",
      profilePic: "",
    },
    validationSchema: Yup.object({
      firstname: Yup.string()
        .max(20, "First Name must not be more that 20 characters")
        .required("Required*"),
      lastname: Yup.string()
        .max(20, "Last Name must not be more that 20 characters")
        .required("Required*"),
      gender: Yup.string().required("Required*"),
      dob: Yup.string().required("Required*"),
      email: Yup.string()
        .email("Must be a Valid Email Address")
        .required("Required*"),
      oldPassword: Yup.string().min(
        6,
        "Your password must be more than 6 characters"
      ),
      newPassword: Yup.string().min(
        6,
        "Your password must be more than 6 characters"
      ),
      confirmNewPassword: Yup.string(),
    }),
    onSubmit: (values) => {
      console.log(values);
    },
  });

The error I get is Cannot read properties of undefined (reading 'firstname') if I could get a way make useFormik render just after the API request it'd help

CodePudding user response:

You can overcome this issue by using a loading component. Display a loading spinner while the initial values are being fetched from the server and when the payload arrives, send it as a prop to your form component. In this way, you will also avoid showing an empty form which is prefilled after a random amount of time to the user.

CodePudding user response:

what you can do after api call in useEffect set values below sample code for further understanding isEmpty is from lodash you can use some alternate if you want for checking if data is not empty

useEffect(() => {
    if (!isEmpty(data)) {
      formik.setValues({
        ...data
      });
    }
  }, [data]);
  • Related