front_dev_j
front_dev_j

Reputation: 169

getting only file path and not object when uploading file in react with yup

I am validating image file size and format with formik yup in react.But when i upload file i get only file path and not the object with that includes type and size property, so i am not able to validate it, i don't know what i am doing wrong here.I reserached a lot and everything i found is using type and size property but i am not getting that property,please help i will surely upvote if it solve my issue. This is my code :

import React from "react";
import { useFormik } from "formik";
import * as Yup from "yup";
import girlImage from "../../images/girl_img.png";
import "./Signup.css";
const SUPPORTED_FORMATS = ["image/jpg", "image/jpeg", "image/gif", "image/png"];
function Signup() {
  const phoneRegExp = /^[6-9]\d{9}$/;
  const SUPPORTED_FORMATS = [
    "image/jpg",
    "image/jpeg",
    "image/gif",
    "image/png",
  ];
  const formik = useFormik({
    initialValues: {
      photo: "",
      name: "",
      email: "",
      phone: "",
      password: "",
      cpassword: "",
    },
    validationSchema: Yup.object({
      email: Yup.string().email("invalid email").required("required"),
      phone: Yup.string()
        .matches(phoneRegExp, "Phone number is not valid")
        .required("phone number is required"),
      password: Yup.string().required("Password is required"),
      name: Yup.string()
        .min(15, "min 15 characters are required")
        .required("name is required"),
      cpassword: Yup.string().oneOf(
        [Yup.ref("password"), null],
        "Passwords must match"
      ),
      photo: Yup.mixed()
        .nullable()
        .required("required field")
        .test("FILE_SIZE", "uploaded file is too large", (value) => {
          console.log(value);
          return value[0].size >= 1000000;
        })
        .test(
          "FILE_FORMAT",
          "uploaded file has unsupported file format",
          (value) => !value || SUPPORTED_FORMATS.includes(value?.type)
        ),
    }),
    onSubmit: (values) => {
      console.log(values);
      formik.resetForm();
    },
    validateOnMount: false,
    validateOnBlur: false,
    validateOnChange: false,
  });
  return (
    <div className="signup">
      <div className="container">
        <div className="two-col-wrap">
          <div className="left-block">
            <h1 className="title">Signup</h1>
            <form onSubmit={formik.handleSubmit} onReset={formik.handleReset}>
              <div className="form-control">
                <label htmlFor="photo" id="photo-label">
                  Photo +
                </label>
                <input
                  type="file"
                  id="photo"
                  {...formik.getFieldProps("photo")}
                />
                {formik.errors.photo ? <p>{formik.errors.photo}</p> : null}
              </div>
              <div className="form-control">
                <label htmlFor="name">Name</label>
                <input
                  type="text"
                  id="name"
                  {...formik.getFieldProps("name")}
                />
                {formik.errors.name ? <p>{formik.errors.name}</p> : null}
              </div>
              <div className="form-control">
                <label htmlFor="email">Email</label>
                <input
                  type="email"
                  id="email"
                  // name="email"
                  autoComplete="username"
                  // value={formik.values.email}
                  // onChange={formik.handleChange}
                  {...formik.getFieldProps("email")}
                />
                {formik.errors.email ? <p>{formik.errors.email}</p> : null}
              </div>
              <div className="form-control">
                <label htmlFor="phone">PhoneNo</label>
                <input
                  type="tel"
                  id="phone"
                  {...formik.getFieldProps("phone")}
                />
                {formik.errors.phone ? <p>{formik.errors.phone}</p> : null}
              </div>
              <div className="form-control">
                <label htmlFor="password">Password</label>
                <input
                  type="password"
                  id="password"
                  // name="password"
                  autoComplete="new-password"
                  // onChange={formik.handleChange}
                  {...formik.getFieldProps("password")}
                />
                {formik.errors.password ? (
                  <p>{formik.errors.password}</p>
                ) : null}
              </div>
              <div className="form-control">
                <label htmlFor="cpassword">Confirm Password</label>
                <input
                  type="password"
                  id="cpassword"
                  // name="cpassword"
                  autoComplete="new-password"
                  // onChange={formik.handleChange}
                  {...formik.getFieldProps("cpassword")}
                />
                {formik.errors.cpassword ? (
                  <p>{formik.errors.cpassword}</p>
                ) : null}
              </div>
              <div className="buttons-container">
                <button className="submit-btn" type="submit">
                  submit
                </button>
                <button
                  className="reset-btn"
                  type="reset"
                  onClick={formik.handleReset}
                >
                  Reset
                </button>
              </div>
            </form>
          </div>
          <div className="right-block">
            <img src={girlImage} alt="girl" />
          </div>
        </div>
      </div>
    </div>
  );
}

export default Signup;

Upvotes: 0

Views: 1240

Answers (1)

front_dev_j
front_dev_j

Reputation: 169

I read the file as url using FileReader like this :

 <ImageInput
                  inputProps={{
                    id: "photo",
                    name: "photo",
                    onBlur: () => formik.setFieldTouched("photo"),
                    onChange: (e) => {
                      formik.setFieldValue("photo", e.target.files?.[0]);
                      if (e.target.files?.[0]) {
                        const reader = new FileReader();
                        reader.readAsDataURL(e.target.files?.[0]);
                        reader.addEventListener("load", () => {
                          if (reader.result) {
                            photoString = String(reader.result);
                            localStorage["userPhoto"] = reader.result;
                          }
                        });
                      }
                    },
                  }}
                  onRemove={() => {
                    formik.setFieldValue("photo", null);
                  }}
                />

and then i changed the value of image on submit like this :

 onSubmit: (values, { setSubmitting }) => {
      setSubmitting(false);
      const detail = {
        ...formik.values,
        photo: photoString,
      };
 

Upvotes: 1

Related Questions