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), };