Hello Everyone!
In the previous article, I shared the steps to integrate Google Maps into your React.js Application.
Today, I want to show how to add markers to the map. So, I aim to implement a click on the specific location on the map and save it in a list.
Create New States
First of all, I want to create some new states to show/hide the dialog box, store the dialog box location, and store the clicked location.
// store clicked location
const [selectedLocation, setSelectedLocation] = useState({});
// store show dialog state to add location
const [showDialog, setShowDialog] = useState(false);
// store dialog location
const [dialogLocation, setDialogLocation] = useState("");
Create handleMapClick Function
I created the handleMapClick function to show a dialog box containing a button to add this location to the list.
// handle click on map
const handleMapClick = (mapProps) => {
// checks if location clicked is valid
if (mapProps.detail.placeId) {
const lat = mapProps.detail.latLng.lat;
const lng = mapProps.detail.latLng.lng;
setShowDialog(true);
setDialogLocation({ lat, lng });
setSelectedLocation({ lat, lng });
} else {
// show alert message
alert("Please select the specific location");
}
};
Here, I am checking the placeId of a location, which means it is a location with a name and ID. Otherwise, it will show an alert to select a specific location.
Calling this function in the <Map/>
component.
...
<Map
style={{ borderRadius: "20px" }}
defaultZoom={13}
defaultCenter={markerLocation}
gestureHandling={"greedy"}
disableDefaultUI
onClick={(mapProps) => handleMapClick(mapProps)}
>
...
Once the correct location is clicked, I want to show the button to confirm from the user to add this location.
Show Add Location Button
Here is the code to show the button in the dialog box on the clicked location of the map.
import { InfoWindow } from "@vis.gl/react-google-maps";
...
{showDialog && (
// displays a dialog to add clicked location
<InfoWindow position={dialogLocation}>
<button className="app-button" onClick={onAddLocation}>
Add this location
</button>
</InfoWindow>
)}
<Marker position={markerLocation} />
...
It will show the dialog like this
Here on the "Add this location" button, I passed the "onAddLocation" function to it.
Save Clicked Location in the List
For this, we need a new state to store all the clicked locations.
// store list of all locations selected
const [listOfLocations, setListOfLocations] = useState([]);
// add location to show in a list
const onAddLocation = () => {
// Create a Google Maps Geocoder instance
const geocoder = new window.google.maps.Geocoder();
// Reverse geocode the coordinates to get the place name
geocoder.geocode({ location: selectedLocation }, (results, status) => {
if (status === "OK") {
if (results[0]) {
setListOfLocations([
...listOfLocations,
{ name: results[0].formatted_address, location: selectedLocation },
]);
setShowDialog(false);
}
} else {
console.error("Geocoder failed due to: " + status);
}
});
};
Here I am reverse geocoding the coordinates to get the location name and saving the name and LAT and LNG with it.
Display List of Locations
After successfully storing the location in the list, I want to display the locations with the “View” and “Delete” functions.
<div className="list-container">
{/* checks the location list is not empty */}
{listOfLocations.length > 0 ? (
<div>
<p className="list-heading">List of Selected Locations</p>
{/* displays stored locations */}
{listOfLocations.map((loc) => {
return (
<div
key={loc.location.lat + loc.location.lng}
className="list-item"
>
<p className="latLng-text">{loc.name}</p>
<div style={{ display: "flex" }}>
<AppButton handleClick={() => onViewLocation(loc.location)}>
View
</AppButton>
<AppButton
handleClick={() => onDeleteLocation(loc.location)}
>
Delete
</AppButton>
</div>
</div>
);
})}
) : (
// displays text msg to select a location
<div>
<p className="list-heading">
Select a location from map to show in a list
</p>
</div>
)}
</div>
Now on the View button click, I’ll show the marker to the specific location and the Delete button click will delete the location from the list.
// displays marker on the map for the selected location
const onViewLocation = (loc) => {
setMarkerLocation({ lat: loc.lat, lng: loc.lng });
};
// deletes selected location from the list
const onDeleteLocation = (loc) => {
let updatedList = listOfLocations.filter(
(l) => loc.lat !== l.location.lat && loc.lng !== l.location.lng
);
setListOfLocations(updatedList);
};
Here is the screenshot after all the work.
That’s it for today.
You can check the whole code on my github.
Thank you for reading! Feel free to connect with me on LinkedIn or GitHub.