2

I am having a file upload using Antd design and it makes the file upload fine.

<Upload {...props}>
  <Button icon={<UploadOutlined />}>Upload png only</Button>
</Upload>

Here I have a beforeUplaod function and its code looks like,

const beforeUpload = (file) => {
  const isPNG = file.type === "image/png";
  if (!isPNG) {
    message.error(`${file.name} is not a png file`);
  }
  // return Upload.LIST_IGNORE; (This will work in newer version but I am using older one which is 4.9.4.
}

As I have mentioned in the above code, if the uploaded image is not png then it will remove the uploaded one from current list as we use Upload.LIST_IGNORE but unfortunately I am working in a older version 4.9.4 and it doesn't have any such keyword to remove the inValid upload from the list.

Could you please kindly help me to remove the uploaded invalid item from the list for version 4.9.4?

Working example:

Edit antd upload component as file selector (forked)

Result:

enter image description here

After some try, I have prevented the file to display in the list if it is not valid but unfortunately the delete of the uploaded file doesn't work now (which was working fine before this current implementation).

Edit antd typescript (forked)

3
  • From what I can tell that Upload.LIST_IGNORE is documented as more a "hack" to safely merge/ignore files being uploaded. I don't see any such logic in 4.9.4. I'm unfamiliar with AntD and this specific component, but I'm gathering this is effectively a validation function. Based on the v4.9.4 logic have you tried returning true for files that aren't valid? Commented Apr 14, 2022 at 16:17
  • @DrewReese, I have updated the codesandbox that return true for invalid file but I couldn't see it prevents from uploading to the list, codesandbox.io/s/… Commented Apr 14, 2022 at 16:43
  • @DrewReese, Also updated question with example and result screencast. Please kindly take a look. Commented Apr 14, 2022 at 16:51

2 Answers 2

2

I was able to get the removal of selected/uploaded files by implementing an onRemove handler.

Example:

const Uploader = () => {
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const validateFileType = (
    { type, name }: UploadFile,
    allowedTypes?: string
  ) => {
    if (!allowedTypes) {
      return true;
    }

    if (type) {
      return allowedTypes.includes(type);
    }
  };

  const uploadProps = useMemo(
    () => ({
      beforeUpload: (file: UploadFile) => {
        const isAllowedType = validateFileType(file, "image/png");
        if (!isAllowedType) {
          setFileList((state) => [...state]);
          message.error(`${file.name} is not PNG file`);
          return false;
        }
        setFileList((state) => [...state, file]);
        return false;
      },
      onRemove: (file: UploadFile) => {
        if (fileList.some((item) => item.uid === file.uid)) {
          setFileList((fileList) =>
            fileList.filter((item) => item.uid !== file.uid)
          );
          return true;
        }
        return false;
      }
    }),
    [fileList]
  );

  return (
    <Upload multiple {...uploadProps} fileList={fileList}>
      <Button icon={<UploadOutlined />}>Upload png only</Button>
    </Upload>
  );
};

Edit antd-file-upload-validation-in-reactjs

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your prompt and promised answer bro. I have one issue after implementing the onRemove in my code which I have in local Error: i.sstatic.net/Av0p1.png
@HelloWorld You're killing me man. 😆 Looks like you might need to tweak the argument and return type to match whatever TS is saying it needs. The RcFile type is missing some properties.
I am really sorry if I am disturbing you more. But somehow i tried to sort it out using codesandbox and provided the maximum try I done and you provided onRemove but unfortunately I am receiving some error after implementing this inside my app code. I apologize for disturbing/Killing you bro :).
@HelloWorld I was kidding. I've swapped in UploadFile for RcFile and the sandbox still appears to work. I don't have a lot of experience with Typescript, so any help from me from here will effectively be me googling/reading TS documentation. At least we got the file removal part working.
Okay bro, let me try to tweak out something in my app code. But my question and your solution completely meets up and thanks for your valuable solution. Hope I will reach you once again for more help/kidding :) .
1

You can create a state & control the fileList. In new version, we can use Upload.LIST_IGNORE but have a look at the API Section. If you do not want to upload the file, you can simply return false or if you use promise, you can reject with reject(false).

Have a look at beforeUpload in API Section of Upload Component. https://ant.design/components/upload/#API

import { useState } from 'react';
import { Upload, Button, message, UploadProps } from 'antd';
import { UploadOutlined } from '@ant-design/icons';

function App() {
    const [fileList, setFileList] = useState([]);
    const [mode, setMode] = useState(false);

    const uploadProps = {
        multiple: mode,
        fileList,
        beforeUpload: (file, filesArray) => {
            let count = 0;
            let files = filesArray.filter((file) => {
                const isPNG = file.type === 'image/png';
                !isPNG && count++;
                return isPNG;
            });

            if (count > 0) {
                setFileList([]);
                message.error(`${count} Files Not Uploaded. Please Upload PNG File/s`);
                return false;
            }

            // If Mode Is Multiple, Simply Store All Files
            if (mode) {
                setFileList(files);
            } else {
                setFileList((prev) => {
                    let newFiles = [...prev];
                    newFiles.push(file);
                    return newFiles;
                });
            }
            return true;

            // Using Promise
            // return new Promise((resolve, reject) => {
            //  // If Not PNG, Reject The Promise
            //  if (!isPNG) return reject(false);

            //  // Else Set The FileList & Send The File
            //  setFileList([file]);
            //  resolve(file);
            // });
        },
        onRemove: (file) => {
            setFileList((prev) => prev.filter((f) => f.uid !== file.uid));
        }
    };

    console.log(fileList);

    return (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
            <div style={{ marginBottom: '10px' }}>
                <Button type='primary' onClick={() => setMode((prev) => !prev)}>
                    Toggle Mode
                </Button>
            </div>
            <Upload {...uploadProps}>
                <Button icon={<UploadOutlined />}>Upload png only</Button>
            </Upload>
        </div>
    );
}

export default App;

enter image description here

Hope this solve your problem

6 Comments

Thanks for your solution. But if I upload valid file (png image), it displays the file name in red color stating error. For more detail you can take a look at the implementation here codesandbox.io/s/…
Also if we have multiple upload then it will remove already uploaded all valid file as we are using setFileList([]) .
I have updated my answer. If mode is false, means you can upload one file at a time and if true you can upload multiple files. Check the code how i store all the files. Most important, I don't know the exact requirements but if you want to upload files in bulk, just return false otherwise it will upload all the files in that array. Also make sure when you upload the file, remove that file from the array.
In sandbox, if you hover over the upload file, you will see some message that says Not Allowed. That's some sort restriction may be from sandbox or you need to add some code to allow upload. You can check the screenshot i attach in the solution
Bro, do you have any idea about this issue? stackoverflow.com/q/71943426/15916627
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.