Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GoogleMap public api - no methods work #133

Closed
dylantf opened this issue Oct 14, 2015 · 18 comments
Closed

GoogleMap public api - no methods work #133

dylantf opened this issue Oct 14, 2015 · 18 comments

Comments

@dylantf
Copy link

dylantf commented Oct 14, 2015

I'm having an issue accessing any of the methods that should be exposed on the GoogleMap component.

In any of these methods, this.state is undefined:

getBounds () { return this.state.map.getBounds(); }
getCenter () { return this.state.map.getCenter(); }
getDiv () { return this.state.map.getDiv(); }
getHeading () { return this.state.map.getHeading(); }
getMapTypeId () { return this.state.map.getMapTypeId(); }
getProjection () { return this.state.map.getProjection(); }
getStreetView () { return this.state.map.getStreetView(); }
getTilt () { return this.state.map.getTilt(); }
getZoom () { return this.state.map.getZoom(); }
// END - Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#Map
//
// Public APIs - Use this carefully
// See discussion in https://github.com/tomchentw/react-google-maps/issues/62
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#Map
//
// [].map.call($0.querySelectorAll("tr>td>code"), function(it){ return it.textContent; }).filter(function(it){ return !it.match(/^get/) && !it.match(/^set/) && !it.match(/Map$/); })
fitBounds (bounds) { return this.state.map.fitBounds(bounds); }
panBy (x, y) { return this.state.map.panBy(x, y); }
panTo (latLng) { return this.state.map.panTo(latLng); }
panToBounds (latLngBounds) { return this.state.map.panToBounds(latLngBounds); }

@tomchentw
Copy link
Owner

I think it works on the <GoogleMap> component in the example. Could you double confirm?

Code:

_handle_map_zoom_changed () {
this.setState(update(this.state, {
geoStateBy: {
0: {
$merge: {
zoom: this.refs.map.getZoom(),
},
},
1: {
$merge: {
opacity: 0.2+(this.refs.map.getZoom()/14),
},
},
},
}));
}
_handle_marker_click () {
this.setState(update(this.state, {
geoStateBy: {
0: {
$merge: {
zoom: 1+this.refs.map.getZoom(),
},
},
},
}));
}

Demo: https://tomchentw.github.io/react-google-maps/#geojson

@dylantf
Copy link
Author

dylantf commented Oct 15, 2015

this.refs.map.getZoom() doesn't work either for me. Any of the methods off of this.refs.map give me an error in the GoogleMap component, this.state is undefined.

Here's the code I'm using:
https://gist.github.com/dyyylan/849d073d7ab16e9a3860

I tried cloning the repo to set up the gh-pages and see if it worked locally, but none of the pages will load.

@tomchentw
Copy link
Owner

So you can't load examples/gh-pages locally? Weird. What's your node, npm version?

The gist looks okay though. However, in componentDidUpdate, could you try to call this.refs.map.fitBounds() directly? I'm not sure if that's the case.

@dylantf
Copy link
Author

dylantf commented Oct 15, 2015

Same error. The line highlighted is this here:

{
    key: "fitBounds",
    value: function fitBounds(bounds) {
      return this.state.map.fitBounds(bounds); // cannot read property `fitBounds` of undefined
    }
  }

I'm running node 4.1.2 and npm 2.14.4

@tomchentw
Copy link
Owner

Did you load google.mas script before React?

/*
 * This is the modify version of:
 * https://developers.google.com/maps/documentation/javascript/examples/event-arguments
 *
 * Add <script src="https://maps.googleapis.com/maps/api/js"></script> to your HTML to provide google.maps reference
 */

@dylantf
Copy link
Author

dylantf commented Oct 15, 2015

Yes. I should mention the rest of the map stuff is working great, it's just these couple exposed methods that don't work.

@tomchentw
Copy link
Owner

It's really weird. I updated the GeojsonToComponents module to include componentDidUpdate and it works great.

@dylantf
Copy link
Author

dylantf commented Oct 15, 2015

Ok I did some more testing and I was able to reproduce what is causing the problem.

In your examples, the map is loaded as soon as the component is mounted.

If something prevents the component from mounting immediately (i.e. I load data and show a spinner gif before the map is shown on the page), something in the GoogleMap state is not bound

I created a repo so you can see how this happens:
https://github.com/dyyylan/map-error

Do you have any suggestions to work around this?

@tomchentw
Copy link
Owner

I tried to update the Map component to:

    componentDidUpdate() {
        if (this.refs.map) {
            console.log('Zoom level:', this.refs.map.getZoom());
        }
    }

But it doesn't work. Still the error of Uncaught TypeError: Cannot read property 'getZoom' of undefined due to this.state.map is undefined.

@tomchentw
Copy link
Owner

@PanJ
Copy link

PanJ commented Nov 4, 2015

@tomchentw I'm having exact same problem but I cannot view your workaround you posted.

@sijovijayan
Copy link

@Dyyylan @tomchentw , Can you change the value of 'ref' attribute in the component render block ?
Use something like the following

     ref="glmap"

Please let me know the result.

@dylantf
Copy link
Author

dylantf commented Nov 4, 2015

Sorry, I cleaned up some repositories I wasn't using and deleted my fork of this project. @PanJ, the workaround was to just create a wrapper component for the map.

Whichever component the map is in, it must render when the component mounts, or you won't get the api exposed. That was the cause of my issue

@beeant
Copy link

beeant commented Nov 17, 2015

I'm having this problem too after upgrading to newer version.

Uncaught TypeError: Cannot read property 'fitBounds' of undefined

@tomchentw
Copy link
Owner

A reproducible jsfiddle would be appreciated! @beeant

@beeant
Copy link

beeant commented Nov 19, 2015

@tomchentw sorry, it works after I moved options to options props

tomchentw added a commit that referenced this issue Nov 22, 2015
* Ref #92

BREAKING CHANGE: ScriptjsLoader will delegate to GoogleMapLoader when the script is loaded

Before:

```js
<ScriptjsLoader
  hostname={"maps.googleapis.com"}
  pathname={"/maps/api/js"}
  query={{v: `3.${ AsyncGettingStarted.version }`, libraries: "geometry,drawing,places"}}
  loadingElement={
    <div {...this.props} style={{ height: "100%" }}>
      <FaSpinner />
    </div>
  }
  googleMapElement={
    <GoogleMap
      containerProps={{
        ...this.props,
        style: {
          height: "100%",
        },
      }}
      ref={googleMap => {
        // Wait until GoogleMap is fully loaded. Related to #133
        setTimeout(() => {
          googleMap && console.log(`Zoom: ${ googleMap.getZoom() }`);
        }, 50);
      }}
      defaultZoom={3}
      defaultCenter={{lat: -25.363882, lng: 131.044922}}
      onClick={::this.handleMapClick}
    >
      <Marker
        {...this.state.marker}
        onRightclick={this.handleMarkerRightclick}
      />
    </GoogleMap>
  }
/>
```

After:

```js
<ScriptjsLoader
  hostname={"maps.googleapis.com"}
  pathname={"/maps/api/js"}
  query={{v: `3.${ AsyncGettingStarted.version }`, libraries: "geometry,drawing,places"}}
  loadingElement={
    <div {...this.props} style={{ height: "100%" }}>
      <FaSpinner />
    </div>
  }
  containerElement={
    <div {...this.props} style={{ height: "100%" }} />
  }
  googleMapElement={
    <GoogleMap
      ref={googleMap => {
        googleMap && console.log(`Zoom: ${ googleMap.getZoom() }`);
      }}
      defaultZoom={3}
      defaultCenter={{lat: -25.363882, lng: 131.044922}}
      onClick={::this.handleMapClick}
    >
      <Marker
        {...this.state.marker}
        onRightclick={this.handleMarkerRightclick}
      />
    </GoogleMap>
  }
/>
```
@tomchentw
Copy link
Owner

Separating google.maps instance creation with React component mounting completely solves this problem. See #157

@tomchentw
Copy link
Owner

Released v4.6.0

@tomchentw tomchentw removed bug labels Dec 3, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants