Disable bubbles on embedded google maps - google-maps

Any idea how to disable these bubbles on my embedded google map?
I'm embedding this into a react/typescript app with react-google-map
Here is my code :
import React, { FC, useState, useEffect } from 'react'
import GoogleMapReact from 'google-map-react'
import Marker from './Marker'
...
export const SimpleMap : FC<any> = ({}) => {
...
return (
<div style={{ height: '80vh', width: '100%', marginTop: '32px' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: 'redacted' }}
defaultCenter={center}
defaultZoom={zoom}
onChildClick={_onChildClick}
//yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps, places)}
>
</GoogleMapReact>
</div>
)
}

Thank you MrUpisdown: Disable bubbles on embedded google maps
The issue was fixed with setting clickableIcons to false
Also see this answer: disable clickable landmark on google map
const apiIsLoaded = (map: any, maps: any, places: any) => {
map.setClickableIcons(false) // Need to call this to disable POIs
...
}
import React, { FC, useState, useEffect } from 'react'
import GoogleMapReact from 'google-map-react'
import Marker from './Marker'
...
export const SimpleMap : FC<any> = ({}) => {
...
return (
<div style={{ height: '80vh', width: '100%', marginTop: '32px' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: 'redacted' }}
defaultCenter={center}
defaultZoom={zoom}
onChildClick={_onChildClick}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps, places)}
>
</GoogleMapReact>
</div>
)
}

<GoogleMapReact
bootstrapURLKeys={{
key: ''
}}
defaultCenter={centerPosition}
defaultZoom={14}
onChange={onMapChange}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map }) => {
mapRef.current = map;
map.setClickableIcons(false)
}}
>

Related

Image doesn't show up in react render

I want to add an image in a tinder-clone app. I followed the mern stack tutorial on the clever programmer youtube channel. Unfortunately, the image didn't show up in the browser.
This is my code:
import React, { useState } from 'react';
import "./TinderCards.css";
import TinderCard from 'react-tinder-card';
function TinderCards() {
const [people, setPeople] = useState([
{
name: 'Elon Musk',
url: "https://upload.wikimedia.org/wikipedia/commons/3/34/Elon_Musk_Royal_Society_%28crop2%29.jpg",
},
]);
const swiped =(direction, nameToDelete) => {
console.log("removing: " + nameToDelete);
};
const outOfFrame = (name) => {
console.log(name + "left the screen!");
};
return (
<div className="tinderCards">
<div className="tinderCards__cardContainer">
{people.map(person => (
<TinderCard
className="swipe"
key={person.name}
preventSwipe= {["up", "down"]}
onSwipe={(dir) => swiped(dir, person.name)}
onCardLeftScreen={() => outOfFrame(person.name)}
>
<div
style={{ backgroundImage: 'url(${person.url})' }}
className="card"
>
<h3>{person.name}</h3>
</div>
</TinderCard>
))}
</div>
</div>
);
}
export default TinderCards
And this is what I see in the browser:
tinder clone

Google Maps element is just grey in react app

I'm using the react-google-maps package for react, and for some reason when it renders it's just grey. If the responsive state changes then it does appear weirdly.
I've wrapped the package in a custom component for re-usablility, and the code is:
import _ from 'lodash';
import exact from 'prop-types-exact';
import propTypes from 'prop-types';
import withScriptjs from 'react-google-maps/lib/async/withScriptjs';
import { GoogleMap as GMap, withGoogleMap } from 'react-google-maps';
import React, { Component } from 'react';
const apiKey = 'api_key';
const AsyncMap = _.flowRight(
withScriptjs,
withGoogleMap,
)(props => (
<GMap
defaultCenter={props.defaultCenter}
defaultZoom={props.defaultZoom}
onClick={props.onClick}
ref={props.onMapLoad}
>
{props.children}
</GMap>
));
class GoogleMap extends Component {
render() {
return (
<AsyncMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&key=${apiKey}`}
loadingElement={<div>{'loading...'}</div>}
{...this.props}
/>
);
}
}
GoogleMap.propTypes = exact({
containerElement: propTypes.object,
defaultCenter: propTypes.object.isRequired,
defaultZoom: propTypes.number,
mapElement: propTypes.object,
onClick: propTypes.func,
});
GoogleMap.defaultProps = {
containerElement: (<div style={{ height: '250px' }} />),
mapElement: (<div style={{ height: '250px' }} />),
defaultZoom: 5,
onClick: _.noop,
};
export default GoogleMap;
And it's called like so:
<GoogleMap
containerElement={<div className={'overnight-storage-map'} style={{ height: '250px' }} />}
defaultCenter={storageLocation}
defaultZoom={3}
>
<Marker
defaultAnimation={2}
key={`marker-${s.id}`}
position={storageLocation}
/>
</GoogleMap>
The problem ended up being that this was rendered inside an accordion that wasn't expanded by default. I just wrote a function that called the native resize method on the map when the accordion is expanded/collapsed.
import _ from 'lodash';
import exact from 'prop-types-exact';
import propTypes from 'prop-types';
import withScriptjs from 'react-google-maps/lib/async/withScriptjs';
import { GoogleMap as GMap, withGoogleMap } from 'react-google-maps';
import React, { Component } from 'react';
const apiKey = 'api_key';
const AsyncMap = _.flowRight(
withScriptjs,
withGoogleMap,
)(props => (
<GMap
defaultCenter={props.defaultCenter}
defaultZoom={props.defaultZoom}
onClick={props.onClick}
ref={props.onMapLoad}
>
{props.children}
</GMap>
));
class GoogleMap extends Component {
constructor(props) {
super(props);
this.state = {
dragged: false,
};
this.dragged = this.dragged.bind(this);
this.onMapLoad = this.onMapLoad.bind(this);
this.resize = this.resize.bind(this);
}
dragged() {
this.setState({ dragged: true });
}
onMapLoad(map) {
if (!map) return;
this._map = map;
this._mapContext = this._map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
this._mapContext.addListener('drag', this.dragged);
}
resize() {
window.google.maps.event.trigger(this._mapContext, 'resize');
if (!this.state.dragged)
this._mapContext.setCenter(this.props.defaultCenter);
}
render() {
return (
<AsyncMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=${apiKey}`}
loadingElement={<div>{'loading...'}</div>}
onMapLoad={this.onMapLoad}
{...this.props}
/>
);
}
}
GoogleMap.propTypes = exact({
children: propTypes.any,
containerElement: propTypes.object,
defaultCenter: propTypes.object.isRequired,
defaultZoom: propTypes.number,
mapElement: propTypes.object,
onClick: propTypes.func,
});
GoogleMap.defaultProps = {
containerElement: (<div style={{ height: '250px', width: '100%' }} />),
mapElement: (<div style={{ height: '250px', width: '100%' }} />),
defaultZoom: 5,
onClick: _.noop,
};
export default GoogleMap;

react-google-maps not showing on screen

i have a react app and i am integrating google map using react-google-maps. It fetches data of lat and lng using node server.
Map.js
import { withGoogleMap, GoogleMap, Marker } from "react-google-maps";
import React from 'react';
// Wrap all `react-google-maps` components with `withGoogleMap` HOC
// and name it GettingStartedGoogleMap
export const GettingStartedGoogleMap = withGoogleMap(props => (
<GoogleMap
ref={props.onMapLoad}
defaultZoom={3}
defaultCenter={props.centre[0]}
onClick={props.onMapClick}>
{props.markers.marker.map((marke, index) => (
<Marker
{...marke}
onRightClick={() => props.onMarkerRightClick(index)}
/>
))}
</GoogleMap>
));
export default GettingStartedGoogleMap;
Layout.js
//some imports
const calculate = (x)=>{
var lt=0;
var lg=0;
var count=0;
x.marker.map((k,i)=>(
lt+=k.position.lat,
lg+=k.position.lng,
count++
))
var centre=[{lat:lt/count, lng:lg/count}];
return centre;
};
export const Layout = props => (
//some div and other elements working fine witout map
<div id="map"><GettingStartedGoogleMap
containerElement={
<div style={{ height: `100%` }} />
}
mapElement={
<div style={{ height: `100%` }} />
}
centre={()=>calculate(props.restraun)}
onMapLoad={_.noop}
onMapClick={_.noop}
markers={props.restraun}
onClick={_.noop}
/></div>
//other elements
);
export default Layout;
Maps is not shown in front end. I have included script tag with api key. Tried changing height from % to fixed value. But still doesn't work.
Data is of format
restran:{
marker:[
{position:
{lat:'value',
lng:'value'
}
key:'value'
}]}
data is being shown correctly if printed on console from node
Edit 1: It seems to be error with the component itself as i was able to print some text instead of markers.

React+Redux - show InfoWindow on Marker click

I would like to display InfoWindow on Marker click. I followed some tutorials and I used react-google-maps for my project. I would like my app to work like this: "https://tomchentw.github.io/react-google-maps/basics/pop-up-window" but my code is a little bit different.
class Map extends React.Component {
handleMarkerClick(){
console.log("Clicked");
}
handleMarkerClose(){
console.log("CLOSE");
}
render(){
const mapContainer= <div style={{height:'100%',width:'100%'}}></div>
//fetch markers
const markers = this.props.markers.map((marker,i) => {
return (
<Marker key={i} position={marker.location} showTime={false} time={marker.time} onClick={this.handleMarkerClick} >
{
<InfoWindow onCloseClick={this.handleMarkerClose}>
<div>{marker.time}</div>
</InfoWindow>
}
</Marker>
)
})
/* set center equals to last marker's position */
var centerPos;
if(markers[markers.length-1]!== undefined)
{
centerPos=markers[markers.length-1].props.position;
}
else {
centerPos={};
}
return (
<GoogleMapLoader
containerElement={mapContainer}
googleMapElement={
<GoogleMap
defaultZoom={17}
center={centerPos}
>
{markers}
</GoogleMap>
}/>
);
}
}
export default Map;
I got "this.props.markers" from another class component, which fetching data from URL. I am almost sure, that it is easy problem to solve. Currently on marker click in console I got "Clicked" and on Marker close "CLOSE" as you can guess from above code it is because of handleMarkerClick() and handleMarkerClose(). I want to have pop-window with InfoWindow.
What should I do to make it work?
Here is heroku link : App on heroku
Hi I came across the same requirement. I did this (I am using redux and redux-thunk) :
GoogleMap.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
withGoogleMap,
GoogleMap,
Marker,
InfoWindow
} from 'react-google-maps';
import { onMarkerClose } from '../actions/Cabs';
const GettingStartedGoogleMap = withGoogleMap(props => (
<GoogleMap
defaultZoom={12}
defaultCenter={{ lat: 12.9716, lng: 77.5946 }}
>
{props.markers.map( (marker, index) => (
<Marker {...marker} onClick={() => props.onMarkerClose(marker.key)}>
{marker.showInfo &&(
<InfoWindow onCloseClick={() => props.onMarkerClose(marker.key)}>
<div>
<h1>Popover Window</h1>
</div>
</InfoWindow>
)}
</Marker>
))}
</GoogleMap>
));
class CabType extends Component{
constructor(props){
super(props);
}
render(){
if(this.props.cabs.length === 0){
return <div>loading...</div>
}
return(
<div className="map-wrapper">
<GettingStartedGoogleMap
containerElement={
<div style={{ height: '100%' }} />
}
mapElement={
<div style={{ height: '100%' }} />
}
onMarkerClose = {this.props.onMarkerClose}
markers={this.props.showMap ? this.props.markers : []}
/>
</div>
)
}
}
export default connect(store => {return {
cabs : store.cabs,
markers: store.markers
}}, {
onMarkerClose
})(CabType);
Action.js
const getMarkers = (cabs , name) => dispatch => {
let markers = [];
let data = {};
cabs.map(cab => {
if(cab.showMap){
data = {
position: {
lat : cab.currentPosition.latitude,
lng : cab.currentPosition.longitude
},
showInfo: false,
key: cab.cabName,
icon: "/images/car-top.png",
driver: cab.driver,
contact: cab.driverContact,
};
markers.push(data);
}
});
dispatch(emitMarker(markers));
};
function emitSetMarker(payload){
return{
type: SET_MARKER,
payload
}
}
export const onMarkerClose = (key) => dispatch => {
dispatch(emitSetMarker(key))
};
RootReducer.js
import { combineReducers } from 'redux';
import { cabs } from "./Cabs";
import { markers } from "./Markers";
const rootReducer = combineReducers({
cabs,
markers,
});
export default rootReducer;
MarkerReducer.js
import { GET_MARKERS, SET_MARKER } from "../types"
export const markers = (state = [], action) => {
switch (action.type){
case GET_MARKERS:
return action.payload;
case SET_MARKER:
let newMarker = state.map(m => {
if(m.key === action.payload){
m.showInfo = !m.showInfo;
}
return m;
});
return newMarker;
default: return state;
}
};
Sorry for a long post but this is code which is tested and running. Cheers!

React-google-maps re-rendering issue

I'm having some issues with the react-google-maps npm module.
First render, works like a charm.
When re-rendering the map-component i get the classic google-maps error.
Uncaught TypeError: Cannot read property 'offsetWidth' of null
Uncaught (in promise) TypeError: Cannot read property 'componentWillReceiveProps' of null(…)
Because the map object isn't available when rendering?
My google-maps Map Component
import React, { PropTypes } from 'react'
import { GoogleMap, Marker, GoogleMapLoader } from 'react-google-maps'
export class Map extends React.Component {
static propTypes = {
coordinates: PropTypes.object,
markers: PropTypes.array
};
render () {
return (<section onloadstyle={{height: '300px'}}>
<GoogleMapLoader
containerElement={
<div
{...this.props}
style={{
height: '300px',
width: '100%'
}}
/>
}
googleMapElement={
<GoogleMap
ref={(map) => console.log(map)}
defaultZoom={15}
defaultCenter={this.props.coordinates}>
{this.props.markers.map((marker, index) => {
return (
<Marker key={index} {...marker} />
)
})}
</GoogleMap>
}
/>
</section>)
}
}
export default Map
And i use the component like this:
var coordinates = {lat: this.props.item.delivery_address_lat, lng: this.props.item.delivery_address_lng}
var map = this.props.item.delivery_address_lat !== 0 && this.props.item.delivery_address_lng !== 0 ? (<Row id='map'>
<Map markers={[{position: coordinates}]} coordinates={coordinates} />
</Row>) : ''
Is this because the google-maps-react module isn't unmounting the component properly or is it something i've done?
The following is inside head
<script src="https://maps.googleapis.com/maps/api/js?key=MY-KEY"></script>
EDIT
Tried to solve it a non react-redux way and this is by no means a solution since it produces the error message: Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the Map component.
But still, the map re-renders correctly. I tried doing this the redux way of calling passed prop functions & state and set the {map: section} in the state, passing it down from the calling view. Didn't solve a thing and resulted in the same error message, even though it was delayed with setTimeout
Im kind of stuck here, don't know how to solve this.
componentDidMount () {
this.setState({map: null})
setTimeout(() => this.setState({
map: <section onloadstyle={{height: '300px'}}>
<GoogleMapLoader
containerElement={
<div
{...this.props}
style={{
height: '300px',
width: '100%'
}}
/>
}
googleMapElement={
<GoogleMap
ref={(map) => console.log(map)}
defaultZoom={15}
defaultCenter={this.props.coordinates}>
{this.props.markers.map((marker, index) => {
return (
<Marker key={index} {...marker} />
)
})}
</GoogleMap>
}
/>
</section>
}), 300)
}
render () {
if (!this.state) {
return <span />
} else {
return this.state.map
}
}
The solution for the second edit was to clear the setTimeout() call in the componentWillUnmount() function.
You always have to clear intervals & timeouts when the component is unmounting.
componentDidMount () {
this.setState({map: null})
this.timeout = setTimeout(() => this.setState({
map: <section onloadstyle={{height: '300px'}}>
<GoogleMapLoader
containerElement={
<div
{...this.props}
style={{
height: '300px',
width: '100%'
}}
/>
}
googleMapElement={
<GoogleMap
ref={(map) => console.log(map)}
defaultZoom={15}
defaultCenter={this.props.coordinates}>
{this.props.markers.map((marker, index) => {
return (
<Marker key={index} {...marker} />
)
})}
</GoogleMap>
}
/>
</section>
}), 300)
}
componentWillUnmount () {
clearTimeout(this.timeout)
}
render () {
if (!this.state) {
return <span />
} else {
return this.state.map
}
}
This solution isn't a good one and isn't in-line with the react-redux workflow. But it works.