'Change file object to normal object in React
Please apologize me for posting the image, but unfortunately my issue can be represented better through image only.
I am making a file upload using antd upload component.
Once I finished uploading files one by one using multiple upload mode, I get the result as following image.
Here the first two objects are ignored when submitting the form after file upload.
The form data for api call has been sent like this, (Content as undefined for first two objects but works for the last where content value was provided as binary)
Simple working example:
After uploading 2 and more files, please note the console.log(e.fileList); in line no.28 of demo.tsx. The result will be like, (First object with name as File but second one as normal object)
I would like to have both object values in the same format as object. Could you please guide me why after file upload, the last one have normal object and other previous uploaded have File object?
If I upload three files then I have to call three api's in which the payloads are as follows,
Payload of first file api call https://i.stack.imgur.com/s23in.png
Payload of second api call https://i.stack.imgur.com/ZHnKT.png
Payload of third api call https://i.stack.imgur.com/eqYSd.png
So only the last payload has the content as binary whereas other two are undefined which prevents the image from uploading.
Solution 1:[1]
You are sending a file object. You need to use FormData to send files. It allows you to set key/value pairs. I have created a small example with complete form submission. Also attach some screenshot.
import { useState, useMemo } from 'react';
import { Upload, Button, message, Form, Input } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { UploadFile } from 'antd/lib/upload/interface';
import { RcFile } from 'rc-upload/lib/interface';
import { POST } from '../../../utils/https';
import axios from 'axios';
interface FormRule {
title: string;
attachment?: { file: RcFile; fileList: RcFile[] };
}
const Uploader = () => {
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
const [form] = Form.useForm<FormRule>();
const validateFileType = ({ type, name }: UploadFile, allowedTypes: string[] = ['image/png', 'image/jpeg']) => {
return allowedTypes.includes(type!);
};
const uploadProps = useMemo(
() => ({
multiple: true,
beforeUpload: (file: UploadFile) => {
const isAllowedType = validateFileType(file);
if (!isAllowedType) {
message.error(`${file.name} is not PNG file`);
return false;
}
setFileList((prev) => [...prev, file]);
return false;
},
onRemove: (file: UploadFile) => {
setFileList((prev) => prev.filter((item) => item.uid !== file.uid));
}
}),
[]
);
const onSubmit = async (data: FormRule) => {
// You cannot send files like normal data. You need to convert it into buffer...
// Use FormData and attach everything you want to send to send to backend
// If you are using node.js, use multer or any other package of your choice to get all files
// and get Files from req.files and data from req.body
let formData = new FormData();
formData.append('title', data.title);
// Don't get attachment files from data, use fileList State because
// it you use attachment from data, it will have all the files that
// should be not accepted. For example, upload one png file and 1 file other than png or jpeg i.e. txt,
// it will have txt file + png file.
if (!!fileList.length) {
for (const item of fileList) {
formData.append('attachment', new Blob([item as any]));
}
}
// await axios('..', { data: formData, method: 'POST' });
};
return (
<Form form={form} onFinish={onSubmit} layout='vertical'>
<Form.Item label='Title' name='title' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name='attachment' rules={[{ required: true }]}>
<Upload {...uploadProps} fileList={fileList}>
<Button icon={<UploadOutlined />}>Upload png only</Button>
</Upload>
</Form.Item>
<Button type='primary' htmlType='submit'>
Submit
</Button>
</Form>
);
};
export default Uploader;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nouman Rafique |




