In the previous post, React & Mapbox: A Map Made in Heaven, Part 2 we walked through creating the Map Component and importing it into the App Component. This post explains how to fetch external data from the New York City Open Data website.
Fetching Open Data with axios
React relies on third party libraries to fetch data. Today, we'll be using a library called axios, a promise based HTTP client for the browser and node. Let's install the module now, create the folder and file that will contain our database logic:
$ yarn add axios
For this project build, we are going to use an API endpoint of NYC Post Office open source data.
Grab the API Endpoint and look over the list of field names. These are the column names for the properties available on this dataset. The Socrata Open Data API documentation has more details on how to filter and query the incoming data.
Step 1 — Import axios
Here, we're using axios instead of the native fetch API. Install axios in the Map Component with the following:
import axios from 'axios'
Similar to fetch(), axios returns a JavaScript promise; however, now you don’t have to resolve the promise two times, because axios already returns a JSON response for you. Furthermore, when using axios you can be sure that all errors are caught in the catch() block.
Step 2 — Set the initial state to contain a property called postoffices
constructor() is basically a function that invokes when an instance of our class gets initialized. When we call super() we're basically saying invoke the same constructor function that the React library defines for their constructor. In addition to that initialize a state for this component in which buildings is a property and set its value as an empty array. We can then set the state any other time in our application using .setState()
.
constructor(props){ super(props) this.state = { postoffices: [], this.state = { } } }
Step 3 — Use 'getPostoffices()' to make the NYC Post Offices API call
getPostoffices(){ // fetch API data in here }
First, we’ll set the API endpoint to a const as a global variable in our Map Component.
In the getPostoffices()
, we'll load the POST_OFFICE data. componentDidMount() is invoked immediately after a component is inserted into the DOM tree and is a good place to instantiate the network request.
const POST_OFFICE = 'https://data.cityofnewyork.us/resource/bdha-6eqy.json'; axios .get(POST_OFFICE, { // this limits the number of objects returned to 10, as per Socrata documentation params: { $limit: 10 } }) .then((response) => { const postoffices = response.data; this.setState({ postoffice: postoffice }); }) .catch((error) => { console.error("Error: ", error); });
The response we get from the API contains an object called data and that contains other objects. The information we want is available in data.results, which is an array of objects containing the data of individual landmarks. In the promise of that request we set the state of this container component to have landmarks be the value returned from the response. Any time setState is invoked the component re-renders.
Call the getPostoffices()
function inside of the componentDidMount()
method:
componentDidMount() { this.getPostoffices(); }
Alternatively, this can all be done inside the componentDidMount()
, combining the previous two steps.