jquense / yup

Dead simple Object schema validation
MIT License
22.93k stars 934 forks source link

Unable to validate file objects #2138

Closed m-abdullah-nabeel closed 11 months ago

m-abdullah-nabeel commented 1 year ago

I am trying to validate file inputs using Yup and React Hook Form, but instead of getting an error message, it still prints submit the form. The code in simplest which will not work is here,

import { useForm } from "react-hook-form"
import { yupResolver } from "@hookform/resolvers/yup"
import * as yup from "yup"

const schema = yup
  .object({
    firstName: yup.string().required(),
    image: yup.mixed().required(),
  })
  .required()

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  })
  const onSubmit = (data) => console.log(data)

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <p>{errors.firstName?.message}</p>

      <input type="file" {...register("image")} />
      <p>{errors.image?.message}</p>

      <input type="submit" />
    </form>
  )
}

I am expecting it to print the error message but in the console it gives me image : FileList length : 0 and if the file is selected, there should be options like validating file size and properties, but in that case, the output is still present as image : FileList 0 : File {name: '1699100386443.jpg', lastModified: 1699100472450, lastModifiedDate: Sat Nov 04 2023 17:21:12 GMT+0500 (Pakistan Standard Time), webkitRelativePath: '', size: 1849449, …} length : 1 but no way to validate by other parameters. I have tried to validate using several ways from Stackoverflow which includes using solutions like

mixed().test("fileSize", "The file is too large", (value) => {
    if (!value.length) return true // attachment is optional
    return value[0].size <= 2000000
  }),

and

mixed()
.test(
  'FILE_SIZE',
  'File is required',
  value => value && value.size >= 10,
)

But still I am unable to sort the way out. Is this a bug or is there a bug in my code.

jquense commented 12 months ago

Is this a bug or is there a bug in my code.

It's not really possible for me to say, with your half example. Please post a full reproducible example using the issue template

m-abdullah-nabeel commented 11 months ago

Is this a bug or is there a bug in my code.

It's not really possible for me to say, with your half example. Please post a full reproducible example using the issue template

Well, the simplest example, that is still reproducing the issue on my side is the above mentioned code.

import { useForm } from "react-hook-form"
import { yupResolver } from "@hookform/resolvers/yup"
import * as yup from "yup"

const schema = yup
  .object({
    firstName: yup.string().required(),
    image: yup.mixed().required(),
  })
  .required()

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  })
  const onSubmit = (data) => console.log(data)

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <p>{errors.firstName?.message}</p>

      <input type="file" {...register("image")} />
      <p>{errors.image?.message}</p>

      <input type="submit" />
    </form>
  )
}

The issue, I am facing is that, I am expecting this form to be submitted only, if this form contains a valid file. But this doesn't happen, the yup validation for other fields is working alright, but for images, it is not working. On debugging, I have realized that the value of fileinput is already set to image : FileList length : 0, even when I haven't touched the file input, maybe there is way, that if it is null, then yup validates it. I think, since the value of file input variables like image is already something as image : FileList length : 0, so maybe it is considering that this is making the form submit.

jquense commented 11 months ago

Well, the simplest example, that is still reproducing the issue on my side is the above mentioned code.

Please post a full reproducible example using the issue template

This isn't a reproducible example, i can't paste this code somewhere and run it, which is why the issue template is set up to provide a way to link running code. I also can't provide support for react-hook-form, it's not library, i don't know how it works, but i can happily help with yup things if you can narrow it down to a yup thing

liseipi commented 11 months ago

FileList {length: 0} always returns 0