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()
}, [])
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;
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;
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
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} />
);
}
});
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='© <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;
This is it our app is ready. Start the app using
yarn start
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)