DEV Community

Cover image for Learn to render Maps by building a wildfire tracker app - Part 2
Neeraj Mukta
Neeraj Mukta

Posted on

Learn to render Maps by building a wildfire tracker app - Part 2

This is part two of Learn to render Maps by building a wildfire tracker app series. If you missed the part one, you can read it here

Also, the complete source code is here

In the first part we rendered a simple map using leaflet now we'll plot some data (wildfire data) on this map. We're going to use this NASA API.
This is an opensource API which requires no key. You can checkout NASA website from information about their cool Apis.

Now, let's fetch data from the api there are many ways/packages to make http requests but I'm going to use fetch as it is directly available in the modern browsers.
We'll use two common React hooks useState and useEffect to make an API request and set the response data.

Add the following code in the app.js file inside src directory.

   const [eventData, setEventData] = useState([])
   const [loading, setLoading] = useState(false)
   useEffect(()=>{
      const fetchEvents = async () =>{
         setLoading(true)
         const {events} = await (await 
  fetch('https://eonet.sci.gsfc.nasa.gov/api/v2.1/events')).json()
         setEventData(events)
         setLoading(false)
       }
       fetchEvents()
    }, [])

Enter fullscreen mode Exit fullscreen mode

This is simple react stuff making api call, setting state and if you find it difficult to understand this I recommend reading the react docs and comeback here again!

Now, we'll modify the Map component from previous post to take eventData as a prop and also, we'll display a loader until the api returns the response and state has been set.

This how our app.js will look like now.

   import Map from "./components/Map";
   import "./App.css";
   import { useState, useEffect } from "react";
   import Header from './components/Header';
   import Loader from './components/Loader';

  function App() {
    const [eventData, setEventData] = useState([])
    const [loading, setLoading] = useState(false)
    useEffect(()=>{
    const fetchEvents = async () =>{
       setLoading(true)
       const {events} = await (await 
  fetch('https://eonet.sci.gsfc.nasa.gov/api/v2.1/events')).json()
       setEventData(events)
       setLoading(false)
       }
      fetchEvents()
    }, [])

   return (
     <div>
       <Header />
       { !loading ? <Map eventData={eventData} /> : <Loader /> }
     </div>
   );
 }

 export default App;
Enter fullscreen mode Exit fullscreen mode

Tip : const {events} = await (await fetch('https://eonet.sci.gsfc.nasa.gov/api/v2.1/events')).json()
This is called object destructing, more details.

And this our simple Loader component. You can get that gif file from source code

  import fireLoader from './fireLoader.gif'

   const Loader = () => {
      return (
          <div className="loader">
             <img src={fireLoader} alt='fireLoader'/>
              <h2>Loading ...</h2>
          </div>
      )
   }

   export default Loader;
Enter fullscreen mode Exit fullscreen mode

Great, Now let's look at the response and we can see that it has an events array which includes information about different natural events like Storms, wildfire, cyclones etc.
But, we only need wildfire co-ordinates from the events array which has id as 8 inside the categories object.
So, we need to filter out all the objects whose id is 8 inside the categories object

NASA API Response

Let's now update our Map component a bit to use eventData prop, add the following code to the Map component.

   // define constants
   const NATURAL_EVENT_WILDFIRE = 8;

     const Map = ({ center, zoom, eventData }) => {
     const markers = eventData.map((event, key) => {
        if (event.categories[0].id === NATURAL_EVENT_WILDFIRE) {
          const [lng, lat] = event.geometries[0].coordinates;
       return (
         <LocationMarker key={key} lng={lng} lat={lat} info= 
          {event.title} />
         );
        }
     });

Enter fullscreen mode Exit fullscreen mode

As you can notice we're looping through the eventData array and looking for objects with id equals to 8 and get the longitute and latitude array as well as event title to display the info about the wildfire when we click on any of the markers.
That's it now we just render the markers array which is an array of all the Location Markers. So, now the complete code for our Map component.

   import React from "react";
   import { MapContainer, TileLayer } from "react-leaflet";
   import LocationMarker from "./LocationMarker";

   // define constants
   const NATURAL_EVENT_WILDFIRE = 8;

   const Map = ({ center, zoom, eventData }) => {
      const markers = eventData.map((event, key) => {
       if (event.categories[0].id === NATURAL_EVENT_WILDFIRE) {
          const [lng, lat] = event.geometries[0].coordinates;
        return (
         <LocationMarker key={key} lng={lng} lat={lat} info= 
          {event.title} />
        );
      }
    });

    return (
       <MapContainer style={{ height: "100vh" }} center={center} 
           zoom={zoom}>
          <TileLayer
            attribution='&copy; <a 
             href="http://osm.org/copyright">OpenStreetMap</a> 
             contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
         />
        {markers}
      </MapContainer>
    );
   };

   Map.defaultProps = {
      center: [42.3265, -122.8756],
      zoom: 6,
   };

   export default Map;

Enter fullscreen mode Exit fullscreen mode

This is it our app is ready. Start the app using
yarn start

Final App Demo

There is so much you could do with leaflet, you can change tiles, provide navigation and much more and the best part is it's open source. Possibilities are limitless.

I hope you liked this series and if you did please share and follow me devnrj07

Have a Happy and Covid-free New Year!

Top comments (0)