-
Notifications
You must be signed in to change notification settings - Fork 939
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
Accessing google.maps.Map Object #161
Comments
I'm actually not a big fan of exposing a map instance to public. However, this is definitely an issue. How about having a import {triggerEvent} from "react-google-maps/libs/utils";
function componentDidResized () {
triggerEvent(this._googleMapComponent, "resize");
}
// and you'll get `this._googleMapComponent` like this:
<GoogleMap ref={(it) => this._googleMapComponent = it} />
// The implementation of `triggerEvent` is quite simple
function triggerEvent (component, ...args) {
const instance = null /* some magic to get Google Maps instance from react-google-maps component */;
return google.maps.event.trigger(instance, ...args);
} |
That would also be great. Anything that can save me from having to do On 11/30/2015 09:21 PM, Tom Chen wrote:
|
Oh cool! Are you writing a book for React? Looking forward to it. |
Hehe, nah, "in my book" is just like "in my opinion" On 11/30/2015 10:27 PM, Tom Chen wrote:
|
Hahaha, okay. This happen to me. |
I'd appreciate this as well. I'm trying to set the center of the map in a "fire-and-forget" way, where certain events might set the map center, but the user is free to move the map around after that. I'm unable to see how to get the "real" current center in handlers for events like onCenterChanged. I can only get the center that I initially set in props. The only way I can see to set the center through React is through props or state. This setting gets reapplied whenever the component gets updated. So, any time the user clicks on a marker, the map jumps back to the last location the map center was programmatically set. |
Released v4.7.0 |
@bieber what the hell is this? |
The gmail app is reporting the notification email from GitHub as spam. |
It is, sorry, my email apparently got cracked :/ |
Sorry to hear this :( @bieber |
The Map object obtained through the ref is not a google.maps.Map Object, it is a react component? Storing this object in a redux store results in a cyclic data structure I think. Is there any way we could obtain the actual google.maps.Map Object? |
@jenyckee yes, it's a React component of course. There is a hacky way to get underlying |
If you use a flux architecture you'll probably want to have access to the map in other components, how can I do this then a not hacky way? |
@jenyckee If you use flux architecture, you can define actions to control the map. The components that wants to update the map can dispatch those actions to fire map updates. The actions are handled by a store that contains the state of the map. Finally the component that renders the map would just use the state in your store to implement the logic to render the map. If you need some programmatic updates that use the original google map object, you can place them in this component in the componentWillMount or componentWillUpdate hook or componentWillReceiveProps hook, depending how you bind your component to store updates. I believe such an approach is usually well decoupled, and not hacky, as your components will not have to rely on implementation details about how to access the original google map instance. |
Hi so what is the hacky way to get the google map instance ?, I'v looked through the code but can't figure it out |
I think this is not convenient way to work with this library, but... const service = new google.maps.places.PlacesService(map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED)
service.nearbySearch({
location: map.getCenter(),
radius: 500,
type: ['store']
}, processResults)
function processResults(results, status, pagination) {
// ...
} Is there any better way to get PlacesService from Google Places API working with |
@michaltakac find a better way? |
@andrewdamelio no. And didn't get fired yet. |
Perhaps I've missed something, but I just realized that the getMap() method is not publicly exposed anymore after upgrading to 6.3. What was the reason behind hiding it? Like other people have mentioned it's still possible to access it through __SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, but is obviously discouraged by the name. So what's the preferred way of accessing the underlying map for creating custom controls etc? |
Ok, so it seems like there is a cleaner way. A list of constants referring to the underlying deprecated identifiers seems to have been added in version 7.0, so we can import the map constant like this:
And since its exposed through context we can access it in the child components like this: Still not an ideal solution, but cleaner than using the reference directly through its deprecated name. |
@sjovall good catch! |
|
@studio174 if you must do such thing, read the source code of v8.0.0. It should be intuitive. react-google-maps/src/components/GoogleMap.jsx Lines 229 to 239 in 030c674
|
@michaltakac find a better way? |
@j-quelly that is the constant used to represent the ominous name of the map instance. You can use it to access the map instance and control is as needed. For example you can disable and enable map controsl like this: import React, {Component} from 'react'
import {withScriptjs, withGoogleMap, GoogleMap} from 'react-google-maps'
import {MAP} from 'react-google-maps/lib/constants'
@withScriptjs
@withGoogleMap
export default class MyGMap extends Component {
state = {
disabled: false
}
componentDidMount () {
this.mapInstance = this.mapNode.context[MAP]
}
componentDidUpdate (prevProps, prevState) {
if (prevState.disabled !== this.state.disabled) {
if (this.state.disabled) {
this.mapInstance.setOptions({
disableDoubleClickZoom: false,
draggable: false,
scrollwheel: false,
zoomControl: false
})
} else {
this.mapInstance.setOptions({
disableDoubleClickZoom: true,
draggable: true,
scrollwheel: true,
zoomControl: true
})
}
}
}
render () {
return (
<div style={{width: '100%', height: '100%'}}>
<a onClick={this.setState((currentState) => ({
disabled: !currentState.disabled
}))}>toggle disabled</a>
<GoogleMap ref={(el) => { this.mapNode = el }} />
</div>
)
}
} |
@sjovall Could you please give an example? I have started to learn React recnetly, and can not see what you mean. |
@jordanpapaleo I tried your code, but got "Cannot read property 'context' of undefined" error. |
@sjovall Here is an example.
I learned from How to handle React context in a reliable way. Thanks |
const google = window.google; it will work please try it . |
I'm running into a little bit of a snag right now, because I'm changing the size of a map's container which means I need to call
google.maps.event.trigger(map, 'resize')
, wheremap
is the google.maps.Map instance associated with the map, to get Google's JS to recognize the newly resized container. What I'm doing now is usingrefToMyGoogleMapInstance.props.map
, which is a horrible hack that's reaching into your component's internal state (and also I'm not exactly sure how it's working at all, because I'm accessing a prop that I never put there myself. I assume it has something to do with all the component cloning you're doing in yourrender
methods). Would you consider adding (or welcome a PR to add) agetMap()
method onGoogleMap
to get easier access to the instance you need for triggering events and whatnot?The text was updated successfully, but these errors were encountered: