Hopp til innhold

Creating Markers on Google Maps

Sercan Leylek

2021.11.05

This is the second post and video in a tutorial series on Google Maps, React, and TypeScript. After setting up Google Maps project in React and rendering the map, the next task is to add markers on the map with click event.

You can watch the tutorial video below and this article serves as a summary of the implementation on YouTube.

IMarker Interface and marker hook

First, we should create an interface for our marker, right? I want to keep three basic data attributes for a marker. Of course, the label of a marker could be also added here as another string value, but I want to keep things simple.

interface IMarker {
    address: string;
    latitude: number;
    longitude: number;
}

Based on this interface, I also create the marker hook which will store the content.

const [marker, setMarker] = useState<IMarker>();

Event Listener

While working with Google Maps on React, you should still write some Vanilla JS code as well. I don’t like this, but we do not have another choice. As soon as the map hook is initialised, we add a click listener into this function. This event listener will return us a LatLng object which will be used to get the coordinates from geocoder.

const initEventListener = ():void => {
    if (map) {
        google.maps.event.addListener(map, 'click', function(e) {
            coordinateToAddress(e.latLng);
        })
    }
};
useEffect(initEventListener, [map]);

Translating coordinate to an address

As you notice, I invoke a function called coordinateToAddress() whenever the user clicks somewhere on the map. The click event of google.maps namespace returns us a typical event (e), but this e event has a special attribute called latLng. This is our location value. In this function, I pull three different data types from geocoder. I get the address, latitute and longitude. Just what I need to set my marker state.

At this point of the program, our Map component successfully retrieves the coordinates of clicked point and it stores the data in our hook (marker), but we do not illustrate any marker to the user, yet.

const coordinateToAddress = async (coordinate: GoogleLatLng) => {
    const geocoder = new google.maps.Geocoder();
    await geocoder.geocode({ location: coordinate}, function (results, status) {
        if (status === 'OK') {
            setMarker({
                address: results[0].formatted_address,
                latitude: coordinate.lat(),
                longitude: coordinate.lng()
            })
        }
    });
};

Adding single marker

I created this function just for convenience. If we decide to create an array of IMarker objects (which means storing several markers on the map at the same time), we would create another function called addMultipleMarkers. But let’s see what addSingleMarker() does first. It simply follows the changes on marker hook with a useEffect and whenever it is updated we invoke addMarker() function.

const addSingleMarker = () => {
   if (marker) {
       addMarker(new google.maps.LatLng(marker.latitude, marker.longitude));
   }
};
useEffect(addSingleMarker, [marker]);

So, here is a much more reusable function. This is actually the moment where our Map component will create the marker and it will show it to the user.

const addMarker = (location: GoogleLatLng): void => {
    const marker: GoogleMarker = new google.maps.Marker({
        position: location,
        map: map,
        icon: getIconAttributes('#000000')
    });
}

google.maps.Marker receives a JSON object where the options are almost limitless. There are so many attributes that you can use to customise your marker, but I only used some fundamental parts here (position, map and icon). I also created a dummy function called getIconAttributes() which is only used for the output of icon. You may refer to Google Maps manual for further customisation.

const getIconAttributes = (iconColor: string) => {
    return {
        path: 'M11.0639 15.3003L26.3642 2.47559e-05L41.6646 15.3003L26.3638 51.3639L11.0639 15.3003 M22,17.5a4.5,4.5 0 1,0 9,0a4.5,4.5 0 1,0 -9,0Z',
        fillColor: iconColor,
        fillOpacity: 0.8,
        strokeColor: 'pink',
        strokeWeight: 2,
        anchor: new google.maps.Point(30, 50)
    };
};

Homework

The gif animation below shows how I create markers on the map, but there is a problem. As I click a point on the map, the component successfully creates a marker. However, when I create once more, the previous marker is still there although the marker hook changed its value. So, try to create a function which will remove the previous marker. Good luck!

I hope you enjoyed the part two. Third video and tutorial will show you how to calculate distance between markers.

(This article was previously published on Stork's Nest)