I'm creating a React app in which I want to upload multiple CSV files and create an array out of them. I want them to be in the below format.
Currently, I see the output as:
[
{"Name":"user 1","Age":"12","Rank":"2"},
{"Name":"user 2","Age":"13","Rank":"3"},
{"Name":"user 3","Age":"10","Rank":"2"},
{"Name":"user 4","Age":"16","Rank":"1"},
{"Name":"user 5","Age":"14","Rank":"5"},
{"Name":"user 6","Age":"11","Rank":""}
]
and
[
{"Name":"Person 1","Age":"27","Rank":"6"},
{"Name":"Person 2","Age":"32","Rank":"3"},
{"Name":"Person 3","Age":"25","Rank":"2"},
{"Name":"Person 4","Age":"31","Rank":"4"},
{"Name":"Person 5","Age":"22","Rank":"1"},
{"Name":"Person 6","Age":"29","Rank":""}
]
But I want the output as
[
[
{"Name":"user 1","Age":"12","Rank":"2"},
{"Name":"user 2","Age":"13","Rank":"3"},
{"Name":"user 3","Age":"10","Rank":"2"},
{"Name":"user 4","Age":"16","Rank":"1"},
{"Name":"user 5","Age":"14","Rank":"5"},
{"Name":"user 6","Age":"11","Rank":""}
],
[
{"Name":"Person 1","Age":"27","Rank":"6"},
{"Name":"Person 2","Age":"32","Rank":"3"},
{"Name":"Person 3","Age":"25","Rank":"2"},
{"Name":"Person 4","Age":"31","Rank":"4"},
{"Name":"Person 5","Age":"22","Rank":"1"},
{"Name":"Person 6","Age":"29","Rank":""}
]
]
File1:
Name,Age,Rank
user 1,12,2
user 2,13,3
user 3,10,2
user 4,16,1
user 5,14,5
user 6,11,7
File2:
Name,Age,Rank
Person 1,27,6
Person 2,32,3
Person 3,25,2
Person 4,31,4
Person 5,22,1
Person 6,29,5
Here is my code.
import { useState } from "react";
const LoadFiles = () => {
const [files, setFiles] = useState([]);
const [processData, setProcessData] = useState(false);
const [allData, setAllData] = useState([]);
const processCSV = (str, delim = ",") => {
const headers = str.slice(0, str.indexOf("\n")).split(delim);
const rows = str.slice(str.indexOf("\n") + 1, str.length - 1).split("\n");
let nArray = rows.map((row) => {
const values = row.split(delim);
const eachObj = headers.reduce((obj, header, i) => {
obj[header] = values[i];
return obj;
}, {});
return eachObj;
});
setAllData([...allData, { nArray }]);
};
const handleUpload = () => {
Array.from(files).forEach(async (file) => {
const currFile = file;
const reader = new FileReader();
reader.onload = (e) => {
const text = e.target.result;
processCSV(text);
};
reader.readAsText(currFile);
});
setProcessData(true);
};
const handleChange = (e) => {
e.preventDefault();
setFiles(e.target.files);
};
return (
<div id="formWrapper">
<form id="csv-form">
<input
type="file"
accept=".csv"
id="csvFile"
multiple
onChange={(e) => handleChange(e)}
/>
<button
onClick={(e) => {
e.preventDefault();
handleUpload();
}}
>
Upload your csv
</button>
</form>
{processData && console.log(allData)}
</div>
);
};
export default LoadFiles;
Here allData should hold my final array. Where am I going wrong and how can I fix this?
Here is a working codesandbox.
[{[file1.csv content]},{[file2.csv content}]? Please add debugging details: How to debug small programsconsole.loga state variable, one may useuseEffecthook (with an appropriate dependency-array).