I’m working on a React component that allows users to upload files. The files are managed in a state
array where each file has additional metadata such as a unique id
(required for DataGrid
) and a docType field (e.g., INVOICE
).
Here’s the state definition:
export interface EnrichedFile {
id: string; // Unique ID for each file (required for DataGrid)
docType: string; // A description of the file, e.g., INVOICE
file: File; // The actual file object
}
const [selectedFiles, setSelectedFiles] = useState<EnrichedFile[]>([]);
Component Code:
Below is the relevant portion of my component where users can drag-and-drop or browse files to upload:
return (
<Box component="div" className="w-96 overflow-hidden">
.....
</Box>
{selectedFiles.length !== 0 && (
<Animated className="w-full mt-4 h-48" animationIn="fadeInUp" animationOut="fadeOut" isVisible={true}>
<ExDataGrid
processRowUpdate={updateRowHandler}
disableColumnMenu
disableColumnFilter
disableDensitySelector
columnHeaderHeight={36}
slots={{
footer: () => (
<div className="flex justify-center">
<LoadingButton onClick={uploadHandler} variant="contained" color="primary" loading={isPending}>
Upload
</LoadingButton>
</div>
),
}}
columns={columnsDocumentsUpload(deleteFileUpload)}
rows={selectedFiles}
/>
</Animated>
)}
</Box>
);
Upload Process:
When I click the Upload button, I create a FormData object and attempt to append the files and metadata before sending it to the server via Axios. However, the FormData appears to be empty when inspected.
Here is my uploadHandler function:
const uploadHandler = useCallback(async () => {
// Validate that all files have a docType
const hasError = selectedFiles.some(file => file.docType.trim() === '');
if (hasError) {
return toast.error('Please select a document type for all files');
}
// Create FormData object
const formData = new FormData();
selectedFiles.forEach(file => {
if (file.file instanceof File) {
formData.append('files', file.file); // Append the actual file
formData.append('metadata', JSON.stringify({ id: file.id, docType: file.docType })); // Include metadata for each file
} else {
console.error("Invalid file object:", file.file);
}
});
// Debugging: Log FormData entries
for (const [key, value] of formData.entries()) {
console.log(`${key}:`, value);
}
mutate(formData);
}, [selectedFiles, mutate]);
Expected Behavior:
The FormData object should include the appended files (files) and metadata (id, docType) and send them to the server.
Questions:
- Why is the FormData object empty even though selectedFiles contains valid File objects?
- Am I appending files to FormData incorrectly?