I've implemented the Google Maps API in a Vue project, I would've used a library like vue2-google-maps but a college of my told me it was better to use the plain JavaScript API as we might have a lot of markers and in his experience the library really struggled when there were to many markers.
So now I've created this method to render the Google Map - Map on the page using Vue:
methods: {
async generateMap() {
// Start and await Google script
const google = await gmapsInit();
// Create Google Map object
this.map = new google.maps.Map(this.$el, {
zoom: 7,
center: new google.maps.LatLng(52.100886023504415, 5.6446197918489)
});
// Standplaats is an object containg a name, lat, lon and slug
this.standplaatsen.forEach(standplaats => {
const position = {
lat: standplaats.location.latitude,
lng: standplaats.location.longitude
};
// Create the marker and add to map
const marker = new google.maps.Marker({
position: position,
title: standplaats.name,
map: this.map,
});
marker.addListener("click", () => {
const infoWindow = new google.maps.InfoWindow({
content:
`<div>` +
`<h4>${standplaats.name}</h4>` +
`${standplaats.location.street}<br/>` +
`${standplaats.location.zipcode} ${standplaats.location.location}<br/>` +
`<hr/>` +
`<a>${standplaats.posts} opdrachten beschikbaar</a>` +
`</div>`
});
infoWindow.open(this.map, marker);
});
});
},
}
The infoWindow contains an hyperlink (<a>${standplaats.posts} opdrachten beschikbaar</a>), I want to trigger an Vue emit event when this hyperlink is clicked. Since this HTML is being render through the Google API I can't just include an @click event.
The solution I thought of was to include an unique ID to the hyperlink element and then adding an eventListeren directly afterwards, so something like this
marker.addListener("click", () => {
const infoWindow = new google.maps.InfoWindow({
content:
`<div>` +
`<h4>${standplaats.name}</h4>` +
`${standplaats.location.street}<br/>` +
`${standplaats.location.zipcode} ${standplaats.location.location}<br/>` +
`<hr/>` +
`<a id="${standplaats.slug}">${standplaats.posts} opdrachten beschikbaar</a>` +
`</div>`
});
infoWindow.open(this.map, marker);
document.getElementById(`${standplaats.slug}`).addEventListener("click", () => {
console.log('I\'ve been clicked');
});
});
But this doesn't work since it takes a while for the Google API to render the element, the only way I could solve this is wrapping the eventListerener in a 1 second timeout but this whole thing is starting to feel pretty bad practice right about now...
Any suggestions on how to handle this?