0

I was trying to load data into my project from the public folder in the componentDidMount() lifecycle method. However, I didn't get the desired FeatureCollection Object but a pending Promise.

componentDidMount = () => {

    ...

    const data = fetch(`vcd/${this.state.monthFile}`)
        .then(response => response.text())
        .then(async data => {
            return csv2geojson.csv2geojson(data, {
                latfield: 'lat',
                lonfield: 'lng',
                delimiter: ','
            }, (err, data) => {
                if (err) console.log(err);
                console.log(data); // correctly outputs a FeatureCollection, length 30277
                return data;
                // this.setState({ someAttribute: data }) => Also doesn't work.
            })
        })
        .then(data => data); // If to use another Promise chaining, the result would be undefined.

    console.log(data); // a pending Promise

}

My file contains 30277 rows * 3 columns, ~500Kb in size, which I think shouldn't be a problem with data loading, and after consulting the csv2geojson and fetch API, I still can't think of a solution to this problem. I am grateful for any helpful inputs.

EDIT: Using both async-await pattern and chaining another .then would result in undefined.

1
  • Why doesn't this.setState({ someAttribute: data }) work in the promise chain? Commented Aug 21, 2020 at 8:28

2 Answers 2

1

JS Fetch returns a promise so its because you're returning that promise. So just change your code like this it will work;

import React, { useEffect, useState } from "react";

export default function ExampleHooks() {
  const [data, setData] = useState(null);
  var csv2geojson = require("csv2geojson");

  useEffect(() => {
    fetch("https://gw3xz.csb.app/sample.csv")
      .then((response) => response.text())
      .then(async (data) => {
        csv2geojson.csv2geojson(
          data,
          {
            latfield: "lat",
            lonfield: "lng",
            delimiter: ","
          },
          (err, data) => {
            if (err) console.log(err);
            setData(data);
          }
        );
      });
  }, []);

  return <div onClick={() => console.log(data)}>show data</div>;
}

or as a Class Component:

import React from "react";
var csv2geojson = require("csv2geojson");

class ExampleClass extends React.Component {
  state = {
    data: null
  };

  componentDidMount() {
    fetch(`vcd/${this.state.monthFile}`)
      .then((response) => response.text())
      .then(async (data) => {
        csv2geojson.csv2geojson(
          data,
          {
            latfield: "lat",
            lonfield: "lng",
            delimiter: ","
          },
          (err, data) => {
            if (err) console.log(err);
            this.setState({ data: data });
          }
        );
      });
  }

  render() {
    return <div onClick={() => console.log(this.state.data)}>show data</div>;
  }
}

export default ExampleClass;

Working example over here

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

Comments

1

fetch returns a promise, and that is what you save to data. If you want to log the "data", then you have a couple options.

  1. Log it IN the promise chain (you already do that)
  2. Convert over to async/await and await the fetch to resolve/reject

code

componentDidMount = async () => {

    ...

    const data = await fetch(`vcd/${this.state.monthFile}`)
        .then(response => response.text())
        .then(data => {
            return csv2geojson.csv2geojson(data, {
                latfield: 'lat',
                lonfield: 'lng',
                delimiter: ','
            }, (err, data) => {
                if (err) console.log(err);
                console.log(data);
                return data;
            })
        });

    console.log(data); // a resolved/rejected Promise result
}

Edit using-js-native-fetch-api-in-react-componentdidmount-results-in-a-pending-pr

2 Comments

Thanks for the input! I have tried your method above, but the data results in undefined. I have also tried to chain another .then(), and the same result is yielded, i.e. undefined.
@Z.Richard I'm not sure what you may be doing differently, but for my own sanity I tested out both solutions in a codesandbox and this works. Updated answer to include link to sandbox demo.

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.