0

I have a problem when fetching data from a CSV File. Here is my Code:

constructor(props) {
        super(props);
        this.state = {
            data: [],
            isLoading: false,
        };
        console.log(this.state.data) // Data is gone =(
    }

toCSV(response){
        let reader = response.body.getReader();
        let decoder = new TextDecoder('utf-8');

        return reader.read().then(function (result) {
            let data = decoder.decode(result.value);
            let results = Papa.parse(data);
            let rows = results.data;
            return rows;
        });
    }

componentDidMount() {
        this.setState({ isLoading: true });
        let dataNames;
            return fetch('url/someFile.csv')
            .then(response => this.toCSV(response))
            .then(data => console.log(data)) // Data is here
            .then(data => this.setState(
                { data: data, isLoading: false }
            ));
    }

Output inside fetch:

(3) […]
0: Array(4) [ "abc", " 1", "aha", … ]
1: Array(4) [ "def", "2", "test", … ]
2: Array(4) [ "ghi", "3", "something", … ]
length: 6

Output in constructor:

[]
length: 0

I do not understand why this.state is empty. I know that the promise is an asynchronous function but i thougth that this.setState({ data: data, isLoading: false }) would set the data into this.state.data and that the promise is then fulfilled.

I found this solution here, but I could not solve the problem with this: React: import csv file and parse

I also tried to do it with a JSON file because I thought the problem was my toCSV function, but the result was the same....

fetchJSON() {
        fetch(`someJSONfile.json`)
            .then(response => response.json())
            .then(response => console.log(response))
            .then(data =>
                this.setState({
                    data: data,
                    isLoading: false,
                })
            )
            .catch(error => console.log(error));
    }

I hope one of you might have an idea. Thanks for your time :)

Liandri
  • 3
  • 1
  • 1
    The constructor is called before `componentDidMount`. You are initializing `data` with an empty array and log it immediately... why did you expect to see values set in a completely different function called at a different moment in time? – Felix Kling Sep 24 '20 at 13:07
  • Oh such a simple solution. That solved my problem. I put the console.log into the render function as Peter suggested and now the Data is there. Thank you. – Liandri Sep 24 '20 at 13:28

2 Answers2

0

Constructor will run only once. With React.Component the render() method will rerun on state change check it:

render(){
 console.log(this.state);
 return <h1>Hello World</h1>
}
Peter
  • 1,280
  • 8
  • 15
0

You have an extra .then which doesn't have this data. The code below should work for you.

componentDidMount() {
        this.setState({ isLoading: true });
        let dataNames;
            return fetch('url/someFile.csv')
            .then(response => this.toCSV(response))
            .then(data => {
                console.log(data)
                this.setState({ data: data, isLoading: false })
            })
    }

also, console.log is not in the appropriate place, if you want to log things to check it out, it should be placed after the execution of setState.

Asim Khan
  • 1,969
  • 12
  • 21