google-mapsgoogle-maps-advanced-marker-element

Get Reference to Original Google Advanced Map Marker in Click Event


I am creating a class to launch a modal with an embedded Google map having various functionality. One of the methods is to add an Advanced Map Marker upon click, and then remove it upon subsequent click. Since these markers are added through a click event, they are essentially anonymous. When a marker is clicked after added, it sends an event with the following parameters { domEvent, latLng }.

My question is, how do I reference the original Marker object that was created upon clicking the Map so that I may remove it?

Here’s a simple example:

class MapModal {

 map;

 constructor() {
  this.initMap(); // we'll assume this inits the google map api
  this.map.addListener('click', (evt) => this.#addMarker(evt));
 }

 #addMarker(evt) {
  const marker = new AdvancedMarkerElement({
   map: this.map,
   position: evt.latLng,
  });
  marker.addListener('click', (evt) => this.#evtMarkerClick(evt));
 }

 #evtMarkerClick(evt) {
  const target = evt.domEvent.target; // a <path> element
  // now I need a reference to remove it:
  const theOriginalMarker = ?;
  theOriginalMarker.map = null;
 }
  
 initMap() {
  // do init stuff
 }
}

I get that I can wrap the marker click event within the method like so:

#addMarker(evt) {
 const marker = new AdvancedMarkerElement({
  map: this.map,
  position: evt.latLng,
 });
 const event = marker.addEventListener('click', (evt) => {
  // listener is nested
  marker.map = null;
  google.maps.event.removeListener(event);
  
 });
}

And also, I can assign a method directly as an Event listener and use the 'this' keyword:

marker.addListener('click', this.#evtMarkerClick);
#evtMarkerClick(evt) {
 const marker = this;
 // now I lose reference to the class instance
}

This may be the way I end up doing it, but I would really like to know how to reference the original object for clarity.


Solution

  • The AdvancedMarker class provides the addEventListener method but registers this with gmp-click as the event type. Using that method means you can easily access custom properties assigned to the marker via the event.target interface. So:

    If you were to add a new method to your MapModal class like this:

    createid(){
        return window.URL.createObjectURL( new Blob( [] ) ).split('/').pop()
    }
    

    That method will generate a pretty good unique ID which can be assigned to each marker as a custom property/attribute - such as id

    The addMarker method:

    addMarker(evt) {
        const id=this.createid();   // create the custom id property
        
        const marker = new AdvancedMarkerElement({
            map: this.map,
            position: evt.latLng,
        });
        marker.id=id;
        marker.addEventListener('gmp-click', this.evtMarkerClick );
        
        this.markers[ id ]=marker;
    }
    

    Then you could change the evtMarkerClick method like this:

    evtMarkerClick(e) {
        const theOriginalMarker = this.markers[ e.target.id ];
        console.log( e.target.id, theOriginalMarker );
        this.markers[ id ].setMap( null );
        delete this.markers[ id ];      
    }
    

    a proof of concept