When you click on a location inside the map using the Google Maps API it displays an info window with the name, address, and link to view it on Google Maps.
Is there a way to override this event and supply it with my own data & styles?
So far I added an onClick listener that looks for events with a placeId property, grabs data for that place, and displays it in an InfoWindow component.
However, this doesn't prevent the default window from opening. It still opens and then gets covered by mine. Works but not exactly what I'm hoping to accomplish.
I either want to completely prevent the default one from showing, OR, apply my changes directly to it and not need to have this separate event handler.
async function handleOnClick(event) {
setContent(undefined);
const latitude = event.latLng.lat();
const longitude = event.latLng.lng();
if (event.placeId) {
const request = {
placeId: event.placeId,
fields: ['name', 'formatted_address', 'place_id', 'geometry', 'photo'],
};
const placesService = new google.maps.places.PlacesService(map);
placesService.getDetails(request, (place, status) => {
if (status === 'OK') {
const info = (
<InfoWindow
position={{
lat: place?.geometry?.location?.lat(),
lng: place?.geometry?.location?.lng(),
}}
onCloseClick={() => setContent(undefined)}
>
<div>
<h3>{place.name}</h3>
<div className='photo-gallery'>
{place?.photos.map((photo) => {
return <img className='photo' src={photo.getUrl()} />;
})}
</div>
</div>
</InfoWindow>
);
setContent(info);
}
});
}
}
I doing this in react with the @react-google-maps/api library
event.stop()
method for POI click event to prevent the Info Window from showing while still processing the Place ID (EDITED)There's an option on MapOptions
called clickableIcons
where you can set to false
, which would disable the click capability on the default POI icons/markers.
Unfortunately, this would also disable the feature where you can have the placeId
of the icon using the map.addListener()
What I would suggest is for you to file a Feature Request that would enable developers to modify the content of the default POIs when clicked. https://developers.google.com/maps/support#issue_tracker
But since the Google Maps API currently does not have this feature, one workaround (Thanks to OPs comment), is to turn off the event with event.stop
once you have the place ID on POI click.
Here's how it should work using the code OP provided:
Create an Info Window state hook to store the contents later on and generate the Component.
const [infoWindow, setInfoWindow] = React.useState(null);
Inside the onLoad callback definition, you check if the Place ID is available. Then if is true, you fire the event.stop()
method to prevent the default Info Window from showing and proceed in processing the fetched Place ID with Places API Place Details and put those data on the custom Info Window you will render on the clicked POI icon.
const onLoad = React.useCallback(function callback(map) {
map.addListener("click", (event) => {
if (event.placeId) {
// once the check for Place ID is done,
// fire the event.stop() here to prevent the default Info Window from showing
event.stop();
// Proceed in processing the Place Details request
// and create the custom Info Window based on the fetched data
const request = {
placeId: event.placeId,
fields: [
"name",
"formatted_address",
"place_id",
"geometry",
"photo",
],
};
const placesService = new google.maps.places.PlacesService(map);
placesService.getDetails(request, (place, status) => {
if (status === "OK") {
// store the Info Window component inside a variable,
// This will be put inside the Info Window state hook later.
const info = (
<InfoWindow
position={{
lat: place?.geometry?.location?.lat(),
lng: place?.geometry?.location?.lng(),
}}
onCloseClick={() => setInfoWindow(null)}
>
<div>
<h3>{place.name}</h3>
<div className="photo-gallery">
{place?.photos.map((photo) => {
return <img className="photo" src={photo.getUrl()} />;
})}
</div>
</div>
</InfoWindow>
);
// Update the Info Window state hook here.
setInfoWindow(info);
}
});
}
});
}, []);
Then you just put the infoWindow
state hook inside the GoogleMap
component to show the Info Window when the details are provided.
return isLoaded ? (
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={15}
onLoad={onLoad}
onUnmount={onUnmount}
>
{infoWindow ? infoWindow : null}
</GoogleMap>
) : (
<></>
);
After all that, it should look something like this:
Here's a proof of concept code sandbox that you can try and play around: https://codesandbox.io/p/sandbox/poi-click-infowindow-tfxjjw
NOTE: Use your own API KEY