2
votes

I'm using Yup with Formik and i run into problem, where I need to validate my file-upload. Validation works, but I'm facing problem, because I can't submit form without file. I need to make it notRequired and because initialValue is undefined it test that undefined value.

My code:

    attachment: Yup.mixed()
        .nullable()
        .notRequired()
        .test("FILE_SIZE", "Uploaded file is too big.", value => value && value.size <= FILE_SIZE)
        .test("FILE_FORMAT", "Uploaded file has unsupported format.", value => value && SUPPORTED_FORMATS.includes(value.type))
2

2 Answers

3
votes

The problem here is that the two .test are making it not valid.

value => value && value.size <= FILE_SIZE and value => value && SUPPORTED_FORMATS.includes(value.type) will fail every time value is undefined or null, but it shouldn't fail by what you are saying.

So you need to do some checking. If the value is null or undefined, it's valid, but if it isn't, do other checkings.

So what you need is

attachment: Yup.mixed()
    .nullable()
    .notRequired()
    .test("FILE_SIZE", "Uploaded file is too big.", 
        value => !value || (value && value.size <= FILE_SIZE))
    .test("FILE_FORMAT", "Uploaded file has unsupported format.", 
        value => !value || (value && SUPPORTED_FORMATS.includes(value.type)))
1
votes

You can use 'useRef' to access file size.

import React, { useRef } from 'react'
import { Field, ErrorMessage, useFormik, Formik, Form } from 'formik'

    const filesharhe_ref = useRef()
        const validationSchema = Yup.object({
                myfile: Yup.mixed().test('FILE_SIZE', "Uploaded file is too big."
                ,(value) => {
                   return(
                    value && filesharhe_ref.current ?
                        (filesharhe_ref.current.files[0].size<=FILE_SIZE? true: false)
                         : true)
                }),
            })
    
    <!-- Component-->

    <Field innerRef={filesharhe_ref} type="file" name="myfile" />
    <ErrorMessage name='myfile'  />

don't forget to define FILE_SIZE.

Also you can check file format:

Yup.mixed().test('FILE_SIZE', "Uploaded file is too big."
                ,(value) => {
                   return(
                    value && filesharhe_ref.current ?
                        (filesharhe_ref.current.files[0].size<=FILE_SIZE? true: false)
                         : true)
                }).test(
                'FILE_Type', "Not valid!"
                , (value) => {
                    console.log(filesharhe_ref.current.files[0])
                    return (
                        value && filesharhe_ref.current ?
                            (SUPPORTED_FORMATS.includes(filesharhe_ref.current.files[0].type) ? true : false)
                            : true)
                }
            )