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.
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 ];
}