0

I have a map that gets the user location from the viewport coordinates, then it uses those coordinates to fetch the markers from an API. Problem is my markers only show up AFTER I move the map. I am confused as to what I'm missing:

componentDidMount(){
        this.getInitialPosition();
        this.fetchLocations();
        this.getMarkers();
    }

Then my function to determine the user's location:

getInitialPosition = () => {
        navigator.geolocation.getCurrentPosition(position => {
            let newViewport = {
                height: "100vh",
                width: "100vw",
                latitude: position.coords.latitude,
                longitude: position.coords.longitude,
                zoom: 15
            }
            this.setState({
                viewport: newViewport
            });
        });
    }

Then I get the markers from my API:

fetchLocations = () => {
        fetch(`http://localhost:3000/locations/${this.state.viewport.latitude}/${this.state.viewport.longitude}`)
        .then(resp => resp.json())
        .then(locations => this.setState({locations}))
    }

And finally the markers:

getMarkers = () => {
        return this.state.locations.map(location => {
            return (
                <Marker key={location.id} offsetLeft={-25} offsetTop={-70} latitude={parseFloat(location.lat)} longitude={parseFloat(location.lng)}>
                    <div className="marker-styles" onClick={() => {this.handleLocationClick(location.id)}} >
                        <p>{location.reviews}</p>
                    </div>
                </Marker>
            );
        });
    }

Then later when I call the map:

                <MapGL
                    {...this.state.viewport}

                    onClick={this.mapClick}
                    attributionControl={false}
                    onViewportChange={this.onViewportChange}
                    mapboxApiAccessToken={TOKEN}
                    mapStyle="mapbox://styles/mapbox/streets-v10">
                    {this.getMarkers()}                        
                </MapGL>

I get the map, but I don't get the markers. Can someone point me in the right direction? I think the issue lies in my shaky grasp on promises and component lifecycle, but I honestly haven't been able to figure this one out. I pasted the full (messy) code here: https://pastebin.com/j8dzYAsk

JohnFajardo
  • 95
  • 1
  • 8

1 Answers1

0

The issue is that getInitialPosition and fetchLocations are asynchronous - and the data they get has not yet been fetched when you call getMarkers

Firstly, I made getInitialPosition return a Promise, that way it's easy to work with fetchLocations once it too returns the Promise returned by fetch

Then it's simply a case of waiting for those two promises to resolve, using Promise.all, and once that's all finished, you call this.getMarkers

componentDidMount(){
    Promise.all([
        this.getInitialPosition(),
        this.fetchLocations()
    ]).then(this.getMarkers);
}
getInitialPosition = () => {
    return new Promise((resolve, reject) => {
        navigator.geolocation.getCurrentPosition(position => {
            let newViewport = {
                height: "100vh",
                width: "100vw",
                latitude: position.coords.latitude,
                longitude: position.coords.longitude,
                zoom: 15
            }
            this.setState({
                viewport: newViewport
            });
            resolve();
        });
    });
}
fetchLocations = () => {
    return fetch(`http://localhost:3000/locations/${this.state.viewport.latitude}/${this.state.viewport.longitude}`)
    .then(resp => resp.json())
    .then(locations => this.setState({locations}));
}
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Thank you so much for your answer. It still did't work for some reason. I only get the markers *after* I drag the map around. Any clue? – JohnFajardo Oct 01 '19 at 18:03