I have implemented Drag and Drop File Upload in my react project, so on every drag and drop of file into the drop zone , I’m taking the file and accessing it’s name and it’s data and converting the data to base64 using javscript’s FileReader()
and readAsDataURL()
and updating the state, which I need to send it to bakend.
How to append a number to filename if the file with same name already exist in the state ?
eg: file(1).csv
or file 2.csv
Main State
this.state : {
Files:[],
}
Function that get’s triggered every time for drag and drop of file
FileHandling = (files) => {
files.forEach((file) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const CompleteData= {
fileData: reader.result,
fileName: file.name,
};
this.setState({
Files:[this.state.Files, CompleteData]
})
};
});
};
Advertisement
Answer
You can check this.state.Files
before. A recursive function could be used here. Imagine you load a file named export.csv
. The second one would export.csv
transformed in export_1.csv
. But on a third one named export.csv
, the verification would be done on export
, leading to export_1
=> Error !
The best is to do :
const checkNameOfTheFile = (newFileName) => {
// Ex 'export.csv'
const counter = this.state.Files.filter(f => f.fileName === newFileName).length;
// If counter >= 2, an error has already been passed to the files because it means
// 2 files have the same name
if (counter >= 2) {
throw 'Error duplicate name already present';
}
if (counter === 0) {
return newFileName
}
if (counter === 1) {
const newName = `${newFileName.split('.')[0]}_${counter}.${newFileName.split('.')[1]}`;
// Return export_1.csv;
return checkNameOfTheFile(newName);
// We need to check if export_1.csv has not been already taken.
// If so, the new name would be export_1_1.csv, not really pretty but it can be changed easily in this function
}
};
const CompleteData= {
fileData: reader.result,
fileName: checkNameOfTheFile(file.name),
};