Burger Map: Fetching and Displaying Data with React

Learning web development can be pretty dreary and gray. So it's always good to involve things you like into your learning process.
Ania Kubów made a Burger API in her YouTube Video How to mock your own API.

I took the liberty and used that API to create a Burger Map with React. And here i show you how.

List of content

Create React App

Let's setup our frontend application by typing the following command into your terminal:

npx create-react-app burger-map

This command will boilerplate a complete react application for you.

Jump into your project with cd burger-map and then start the development server with yarn start,

This will start the react application which you can then visit at http://localhost:3000.

Once this is done we can open up this project in the editor of our choice.

In the main file App.js safely remove all the stuff which is not needed the file will look like this:

import './App.css';

function App() {
    return (
        <div className="App">

        </div>
    );
}

export default App;

Fetching Burger Data

The next step is to fetch the data which we want to display. For that purpose we are going to use the npm module axios which will execute our HTTP requests.

Install it with yarn via the terminal:

yarn add axios

To add a state to our application, we need to import the useState hook. Since we want to call up the data right at the beginning of our application, we need the useEffect hook right away.
Import them at the beginning of App.js

import {useState, useEffect} from 'react';

We need one state to set our application into the loading state while fetching data, and one to store the burger data.
Lets to this with this to lines of code:

const [loading, setLoading] = useState(true)
const [burgers, setBurgers] = useState(null)

The function to fetch the data we place the useEffect hook, to be sure it is called right at the beginning of our application.
As mentiond we use axios to handle the get-request.
The URL of the API is where we get the burgers from is https://my-burger-api.herokuapp.com/burgers.

The useEffect hook should now look like this:

useEffect(() => {
    const fetchBurgers = async () => {

        const {data} = await axios.get("https://my-burger-api.herokuapp.com/burgers")

        setBurgers(data)
        setLoading(false)
    }

    fetchBurgers()
}, []);

Mapbox API

For further purposes we need to create an free account at mapbox.com. Then under your Account you can create an Access Token which we need to call the Mapbox Api.
Copy this token and put it in ca const in your application.

const MAPBOX_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Append Latitude and Longitude Values to the Response

When we check the response for e.g. with console.log(data)
we see that currently the address for each burger looks something like that:

[
    {
    addressId: 0
        country: "United Kingdom"
        line1: "Brick Lane"
        line2: "Shoreditch"
        number: "104"
        postcode: "E1 6RL"
    },
    ...
]

Since the Mapbox App is needing the latitude and longitude values to display the data on the correct position we have to call the geocoding endpoint. Here we have to pass the address object as a string seperated with ampersands.

For that case create the getLatLong function like that:

const getLatLong = async (address) => {
    const {line1, line2, number, postcode, country} = address;
    let searchKey = [line1, line2, number, postcode, country].filter(Boolean).join().replaceAll(" ", "&");

    const {data: {features}} = await axios.get(`https://api.mapbox.com/geocoding/v5/mapbox.places/${searchKey}.json?access_token=${MAPBOX_TOKEN}`)

    return features[0].center;
}

Now we need to call this function for each burger so adjust the fetchBurgers function to look like that:

useEffect(() => {
    const fetchBurgers = async () => {
        let burgers = []
        const {data} = await axios.get("https://my-burger-api.herokuapp.com/burgers")

        for (const burger of data) {
            burger.latLong = await getLatLong(burger.addresses[0])
            burgers.push(burger)
        }

        setBurgers(burgers)
        setLoading(false)
    }

    fetchBurgers()
}, []);

Now when we check our burger object we see a property latLong which is an array containing the lat and long values.

Display the World Map

To display the data on a map let's install the ReactMapGL component.

yarn add react-map-gl

Then import the Map as well as the Markers Component at the beginning of our App.

import ReactMapGL, {Marker} from 'react-map-gl';

Let's adjust the return from our App.js and add the Map Component like that:

if (loading) {
    return 'loading burgers..'
}

return (
    <div className="App">
        <div>
            <h1 style={{textAlign: 'center'}}>World Map</h1>
        </div>

        <ReactMapGL
            width="100vw"
            height="100vh"
            mapboxApiAccessToken={MAPBOX_TOKEN}
        >
        </ReactMapGL>
    </div>
);

Now you already should be able to see a fullscreen map in your browser.

To make our map interactive we need to add a so called viewport as well as the function to change it.

So add a new state, as well as adjust the Map Component:

const [vieport, setVieport] = useState({})
<ReactMapGL
    {...vieport}
    width="100vw"
    height="100vh"
    onViewportChange={nextVieport => setVieport(nextVieport)}            
    mapboxApiAccessToken={MAPBOX_TOKEN}
>
</ReactMapGL>

Go and check the map. You can now drag and drop, as well as zoom in and zoom out.

Render Data on the Map

Now we come to the last part. We have to combine the data and the map.

For that create the renderBurgers function and call inside of the ReactMapGL component.
The renderBurgers function maps over all burgers, passes the lat and long values to the Marker and returns them on their location.
Whatever you pass inside the Marker Component will then be displayed on the map. In this case we render a X for each burger.

function renderBurgers() {
    return burgers.map(burger => (
        <Marker
            key={burger.id}
            latitude={burger.latLong[1]}
            longitude={burger.latLong[0]}
        >
            X
        </Marker>
    ))
}

The last step is to call the renderBurgers function in the ReactMapGl Component. So let's add it:

<ReactMapGL
    {...vieport}
    width="100vw"
    height="100vh"
    onViewportChange={nextVieport => setVieport(nextVieport)}
    mapboxApiAccessToken={MAPBOX_TOKEN}
>
    {renderBurgers()}
</ReactMapGL>

Conclusion

In this I showed you how to create a react app, fetch data from an API. Then we used the Mapbox react component to display the data on the Map.

This was my first article ever, if you liked it let me now. And if you didn't liked it let me now what can be improved.

Thanks for reading!

TL;DR

I also made a step by step video for this burger map on my YouTube Channel.

23