MicheleBertoli / react-gmaps

A Google Maps component for React.js
http://react-gmaps.herokuapp.com/
MIT License
317 stars 68 forks source link

onClick on Marker is not sending reference to the Marker #95

Closed malexandrum closed 7 years ago

malexandrum commented 7 years ago

I didn't find a way to get a reference to the Marker object in the onClick handler, could you shed some light? Thanks again!

MicheleBertoli commented 7 years ago

Hello @malexandrum, the click event of the marker returns a MouseEvent object: https://developers.google.com/maps/documentation/javascript/reference#MouseEvent

screen shot 2017-05-17 at 4 56 09 pm

If you need a reference to the marker you need to pass it by yourself, for example by binding the marker to the onClick handler. Hope this helps.

malexandrum commented 7 years ago

@MicheleBertoli i was actually in need of the Google marker object and I don't see how to bind that other than forking your project. Thanks!

MicheleBertoli commented 7 years ago

I'm not sure how forking this repo solves the problem, but here is an example:

import React from 'react';
import ReactDOM from 'react-dom';
import createReactClass from 'create-react-class';
import { Gmaps, Marker } from 'react-gmaps';

const markers = [{
  lat: 51.5258541,
  lng: -0.08040660000006028,
}, {
  lat: 51.5258541,
  lng: -0.04040660000006028,
}];

const App = createReactClass({

  markers: [],

  handleClick(index) {
    console.log('Hello, ', this.markers[index].getEntity());
  },

  render() {
    return (
      <Gmaps
        width={400}
        height={400}
        lat={51.5258541}
        lng={-0.08040660000006028}
        zoom={12}
      >
        {markers.map((marker, index) => (
          <Marker
            ref={el => (this.markers[index] = el)}
            lat={marker.lat}
            lng={marker.lng}
            onClick={() => this.handleClick(index)}
          />
        ))}
      </Gmaps>
    );
  }

});

ReactDOM.render(<App />, document.getElementById('gmaps'));

Hope this helps.

malexandrum commented 7 years ago

@MicheleBertoli Your code makes total sense when you need to know which one of your markers has been clicked, I just needed access to the Google Marker object like we get access to the Google Map object in the onMapCreated handler.

MicheleBertoli commented 7 years ago

What about this?

handleMapCreated() {
  this.markers.forEach(marker => (
    console.log('Hello, ', marker.getEntity())
  ));
},
<Gmaps
  ...
  onMapCreated={this.handleMapCreated}
>

Please let me know if it solves your issue.

malexandrum commented 7 years ago

In this case markers is an array of objects with only lat and lng, no getEntity method.

MicheleBertoli commented 7 years ago

Hello @malexandrum, markers is an array of objects, but I'm looping through this.markers (which is an array of ref nodes) in the example. Sorry for the confusion, you should add the code of the second example to the first one.

This is the final code:

import React from 'react';
import ReactDOM from 'react-dom';
import createReactClass from 'create-react-class';
import { Gmaps, Marker } from 'react-gmaps';

const markers = [{
  lat: 51.5258541,
  lng: -0.08040660000006028,
}, {
  lat: 51.5258541,
  lng: -0.04040660000006028,
}];

const App = createReactClass({

  markers: [],

  handleMapCreated() {
    this.markers.forEach(marker => (
      console.log('Hello, ', marker.getEntity())
    ));
  },

  render() {
    return (
      <Gmaps
        width={400}
        height={400}
        lat={51.5258541}
        lng={-0.08040660000006028}
        zoom={12}
        onMapCreated={this.handleMapCreated}
      >
        {markers.map((marker, index) => (
          <Marker
            ref={el => (this.markers[index] = el)}
            lat={marker.lat}
            lng={marker.lng}
          />
        ))}
      </Gmaps>
    );
  }

});

ReactDOM.render(<App />, document.getElementById('gmaps'));

I hope it's clearer.

malexandrum commented 7 years ago

You're right, I was binding the handler so this was referring to my component instead of the marker. Works as you said, thanks again.