0

I struggle with passing parameters to the onToggleOpen function - I render multiple markers (here only 2 for simplifying) and when I click on a marker, I want to display the respective InfoWindow for it. But when I click on the marker now, the method onToggleOpen is not triggered.

If I remove the indexes from markers and also from onToggleOpen, then the functionality of displaying and hiding InfoWindow boxes - but then all InfoWindow boxes will open and hide at the same time.

How do I properly pass the index to onToggleOpen?

const MyMapComponent = withScriptjs(withGoogleMap((props) =>
  <GoogleMap
    defaultZoom={8}
    defaultCenter={{ lat: -34.397, lng: 150.644 }}
  >
    <Marker 
        key='1'
        position={{ lat: -34.397, lng: 150.644 }} 
        onClick={props.onToggleOpen(1)}
    >
        {props.isOpen && 
            <InfoWindow onCloseClick={props.onToggleOpen}>
                <div>Something 1</div>
            </InfoWindow>
        }
    </Marker>
    <Marker 
        key='2'
        position={{ lat: -33.867855, lng: 151.178897 }} 
        onClick={props.onToggleOpen(2)}
    >
        {props.isOpen && 
            <InfoWindow onCloseClick={props.onToggleOpen}>
                <div>Something 2</div>
            </InfoWindow>
        }
    </Marker>
  </GoogleMap>
))
export default class GoogleMapsSample extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
          isOpen: false
        }
        this.onToggleOpen = this.onToggleOpen.bind(this);
    }

    onToggleOpen(index){
        console.log('x');
        //this.setState({isOpen: !this.state.isOpen})
        if (this.state.isOpen === index) {
            this.state.isOpen = false;
        } else {
            this.state.isOpen = index;
        }
        console.log(this.state.isOpen);
    }

    render() {
        const { isOpen } = this.state;
        console.log('isOpen: ', this.state.isOpen);
        return (
            // Important! Always set the container height explicitly
            <div style={{ height: '100vh', width: '100%' }}>
                <MyMapComponent 
                    googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=AIzaSyDFD30jUKH0Cl8qrZoNCe-eEGQBIfApzE0"
                    loadingElement={<div style={{ height: `100%` }} />}
                    containerElement={<div style={{ height: `400px` }} />}
                    mapElement={<div style={{ height: `100%` }} />}
                    isOpen={isOpen}
                    onToggleOpen={this.onToggleOpen}
                />
            </div>
        );
    }
}

EDIT: I am not sure that the attribute isOpen is changed here

constructor(props) {
    super(props)
    this.state = {
      isOpen: false
    }
    this.onToggleOpen = this.onToggleOpen.bind(this);
}

...

<Marker 
    key='1'
    position={{ lat: -34.397, lng: 150.644 }} 
    onClick={()=>props.onToggleOpen(1)}
>
    {props.isOpen === 1 && 
        <InfoWindow onCloseClick={props.onToggleOpen}>
            <div>Something 1</div>
        </InfoWindow>
    }
</Marker>

because the InfoWindow block is never executed. I thought that in the function where I change the state is something wrong:

onToggleOpen(index){
    //this.setState({isOpen: !this.state.isOpen})
    if (this.state.isOpen === index) {
        this.state.isOpen = false;
    } else {
        this.state.isOpen = index;
    }
}

but here the this.state.isOpen attribute is properly changed (tested with console.log). But even though here is isOpen is changed, the InfoWindow is never displayed after clicking on the marker.

I have also tried to set its value in contructor like this:

this.state = {
  isOpen: false
}

and the InfoWindow is displayed after loading the page, but when I click on the marker, nothing happens with the InfoWindow, it will not disappear and stays displayed (even though the values in onToggleOpen() are properly changed).

What am I overlooking here? Am I passing the value isOpen incorrectly to the Marker?

6
  • Does your Map component only ever have Two Markers? Or is it going to be dynamic, and have many markers? The way you are doing it now, and hardcoding values into each one is not a wise, and scaleable idea. Commented Jun 23, 2018 at 13:21
  • It will have many markers, but for simplifying, I only put to the script 2 markers. Commented Jun 23, 2018 at 14:04
  • @DanielZuzevich it looks like props.onToggleOpen is passed correctly, but I think that props.isOpen is not passed properly, because the changed attribute is not reflected in the Marker. I have edited the OP to show the issue. Thank you Commented Jun 23, 2018 at 14:53
  • 1
    There is never any case where you should not be using setState Commented Jun 23, 2018 at 15:06
  • 1
    Oh I spent almost 2 hours thinking about this, totally forgot about this.setState({ isOpen: index });. Still new to React, so it takes me time to put the newly learned things in place. Thank you! Commented Jun 23, 2018 at 15:29

1 Answer 1

1

by writing props.onToggleOpen(1) you are actually calling the function there. but i think you need it to be called when the marker is clicked.

so the correct code of the Marker component should be the following:

<Marker 
    key='1'
    position={{ lat: -34.397, lng: 150.644 }} 
    onClick={()=>props.onToggleOpen(1)}
>
    {props.isOpen && 
        <InfoWindow onCloseClick={props.onToggleOpen}>
            <div>Something 1</div>
        </InfoWindow>
    }
</Marker>

notice ()=>props.onToggleOpen(1). now this will call onToggleOpen when you click the marker.

Sign up to request clarification or add additional context in comments.

2 Comments

Inline arrow function will work. This should give him what he needs.
@InusSaha, @DanielZuzevich it looks like props.onToggleOpen is passed correctly, but I think that props.isOpen is not passed properly, because the changed attribute is not reflected in the Marker. I have edited the OP to show the issue. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.