1

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.

14
  • What is [{[file1.csv content]},{[file2.csv content}]? Please add debugging details: How to debug small programs Commented Apr 20, 2022 at 16:15
  • Updated my question @jabaa Commented Apr 20, 2022 at 16:47
  • What does "currently I see output as" mean? How can one variable contain two arrays? Commented Apr 20, 2022 at 16:52
  • 1
    @Rakesh - here's a working codesandbox link: https://codesandbox.io/s/gifted-cerf-to55i9. BTW: To console.log a state variable, one may use useEffect hook (with an appropriate dependency-array). Commented Apr 20, 2022 at 17:54
  • 1
    I am able to fix that thing @jsN00b, Can you please post the codesandbox link as an answer? I'll accept it. Thanks again! Commented Apr 20, 2022 at 18:51

1 Answer 1

1

As per conversation in the comments, it appears the problem was with below line:

setAllData([...allData, { nArray }]);

A new codesandbox forked which changed the line like this:

setAllData(prev => ([...prev, nArray]));

(and made few other changes) seems to have fixed the issue faced.

It is also pertinent to note that useEffect may be simple way to console.log a state variable. For example, if the state variable we need to log is allData (in the above example), then below may be suitable

useEffect(
  () => console.log(allData),
  [allData]
);

This may be explained like so:

  • Whenever allData changes (noted in the dependency array of the useEffect)
  • Execute the console.log (the call-back of useEffect)

Codesandbox Link with issues fixed: https://codesandbox.io/s/gifted-cerf-to55i9

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.