question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Fitbounds with ref error.

See original GitHub issue

Hi there, how do we do a fitbounds of all the markers in google-map-react? Any example for that?

This is what I done but with error:

const PGoogleMap = compose( withProps({ googleMapURL: https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAP_API_KEY}&v=3.exp&libraries=geometry,drawing,places`, loadingElement: <div style={{ height: 100% }} />, containerElement: <div style={{ height: 400px }} />, mapElement: <div style={{ height: 100% }} /> }), withHandlers(() => { const refs = { map: undefined, } return { onSetFit: () => ref => { refs.map = ref var mBounds = new google.maps.LatLngBounds(); mCoords.forEach((p) => { var latLng = new google.maps.LatLng(p.lat, p.lng); mBounds.extend(latLng); }) ref.map.fitBounds(mBounds) } } }), withScriptjs, withGoogleMap )((props) => <GoogleMap ref={props.onSetFit} defaultZoom={18} defaultCenter={props.centerFocus}

{props.patrol.map((marker, i) => ( <Marker key={marker.id} position={{ lat: marker.lat, lng: marker.lng }} > </Marker> ))} <Polyline path={props.coordinates} /> </GoogleMap> )`

The code is working fine when showing the map. But when I turn to other page without the map, the map will still be mounted on the bottom of the page. Upon checking the console, this error appear ref.map is null. Warning: Exception thrown by hook while handling onSetChildren: Invariant Violation: Expected hook events to fire for the child before its parent includes it in onSetChildren(). Anybody knows how to fix it?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
bossbossk20commented, Nov 23, 2017

@ahgan84 you can use fitBounds()

this is my code it’s working

import React from 'react'
import { compose, withProps } from 'recompose'
import { withGoogleMap, GoogleMap, OverlayView, InfoWindow } from 'react-google-maps'
import styled from 'styled-components'

const cars = [
  {
    image: 'http://lorempixel.com/150/150/people/1',
    name: 'aaaa vvvv',
    tel: '0811111111',
    address: {
      lat: 13.727286,
      lng: 100.568995
    }
  },
  {
    image: 'http://lorempixel.com/150/150/people/2',
    name: 'xcxc xcxc',
    tel: '088888888',
    address: {
      lat: 13.727286,
      lng: 100.668995
    }
  },
  {
    image: 'http://lorempixel.com/150/150/people/3',
    name: 'koykoy koykoy',
    tel: '0855555555',
    address: {
      lat: 13.767286,
      lng: 100.668995
    }
  }
]

// type Props = {}

const CustomMarker = styled.div`
  .pin {
    cursor: pointer;
    width: 50px;
    height: 50px;
    border-radius: 50% 50% 50% 0;
    background-color: #ff3300;
    poisition: relative;
    text-align: center;
    transform: rotate(-45deg);
    .avatar {
      transform: rotate(45deg);
      content: '';
      display: block;
      width: 42px;
      height: 42px;
      border-radius: 50%;
      margin: 4px 0 0 4px;
      overflow: hidden;
      position: absolute;
      translate:(4px, 4px);
      z-index: 1;
    }
  }
    /* transform: rotate(45deg); */
`
const InfoWindowContent = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  img {
    width: 200px;
    height: 200px;
    border-radius: 50%;
  }
  .tel {
    font-size: 18px;
  }
  .latlng {
    font-size: 16px;
  }
`

const getPixelPositionOffset = (width, height) => ({
  x: -(width / 2),
  y: -(height / 2)
})

class Map extends React.Component {
  state = {
    init: false,
    showInfoBox: false,
    selectMarker: null
  }
  handleClosedInfoBox = () => {
    this.setState({
      showInfoBox: !this.state.showInfoBox
    })
  }
  setCenterAndZoom () {
    if (!this.state.init) {
      const bounds = new window.google.maps.LatLngBounds()
      cars.forEach(bound => bounds.extend(new window.google.maps.LatLng(bound.address.lat, bound.address.lng)))
      this.refs.map.fitBounds(bounds)
    }
    this.setState({
      init: true
    })
  }
  handleclickedItem = (item) => () => {
    this.setState({
      selectMarker: item,
      showInfoBox: true
    })
  }
  componentDidMount () {
    // console.log(LatLng)
  }
  render () {
    const { showInfoBox, selectMarker } = this.state
    return (
      <GoogleMap
        ref='map'
        defaultZoom={15}
        defaultCenter={{ lat: 13.727286, lng: 100.568995 }}
        onTilesLoaded={() => this.setCenterAndZoom()}
      >
        {
          cars.map((item, index) => (
            <OverlayView
              position={item.address}
              key={index}
              mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
              getPixelPositionOffset={getPixelPositionOffset}
            >
              <CustomMarker onClick={this.handleclickedItem(item)} >
                <div className='pin'>
                  <img className='avatar' src={item.image} alt='' />
                </div>
              </CustomMarker>
            </OverlayView>
          ))
        }
        {
          showInfoBox && <InfoWindow
            key={Math.random()}
            onCloseClick={this.handleClosedInfoBox}
            position={selectMarker.address}
          >
            <h1>
              <InfoWindowContent>
                <img src={selectMarker.image} />
                <p>{selectMarker.name}</p>
                <span className='tel'>{selectMarker.tel}</span>
                <span className='latlng'>{`${selectMarker.address.lat} , ${selectMarker.address.lng}`}</span>
              </InfoWindowContent>
            </h1>
          </InfoWindow>
        }
      </GoogleMap>
    )
  }
}

// const map = (props: Props) => ()

const MyMapComponent = compose(
  withProps({
    loadingElement: <div style={{ height: `100%` }} />,
    containerElement: <div style={{ height: `calc(100vh - 100px)` }} />,
    mapElement: <div style={{ height: `100%` }} />
  }),
  withGoogleMap
)(Map)

export default MyMapComponent

0reactions
nwaywoodcommented, Jan 2, 2018

@ahgan84 the #713 way. This way is the deprecated way

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Google Map Fitbounds not a function error
When the ref attribute is used on a custom class component, the ref object receives the mounted instance of the component as its...
Read more >
Call map.fitBounds(bounds); produce error "Uncaught ... - GitLab
Hi Ivan, it happens when you try to make a setView or similar on the leaflet map just after creation. Before the _GAPIPromise...
Read more >
Google Maps JavaScript API V3 Reference
This is an index of all the classes, methods, and interfaces in the Maps JavaScript API version 3.51 (weekly channel). This reference is...
Read more >
question on bounds.extend and map.fitbounds - Google Groups
with us. At a guess, you are wishing for the polygon getBounds() method but have not actually implemented the necessary __extension__ to the...
Read more >
Map | Mapbox GL JS
A Map#fitBounds options object to use only when fitting the initial bounds provided above. ... Invalid codes will result in an recoverable error....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found