2
votes

Leaflet and using GeoJSON. I am trying to get the markers from a fetched GeoJSON API to render on the map, once the data is stored on the state. I have tried using the marker component to display the markers from the API but nothing is rendering to the page. I am open to use the marker component or any other way to display the markers. Thanks!

import React, { Component } from "react";
import "./App.css";
import { Map, TileLayer, Marker, Popup, GeoJSON } from "react-leaflet";
import L from "leaflet";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      location: {
        lat: 51.505,
        lng: -0.09
      },
      zoom: 2,
      bikes: null,
      haveUsersLocation: false,
    };

 componentWillMount() {
    fetch(
      "https://bikewise.org:443/api/v2/locations/markers?proximity_square=10"
    )
      .then(response => response.json())
      .then(data => this.setState({ bikes: data }));
  }

 render() {
    const position = [this.state.location.lat, this.state.location.lng];

    return (
      <div className="App">
        <Menu />
        <Map className="map" center={position} zoom={this.state.zoom}>
          <TileLayer
            attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />

          <GeoJSON addData={this.state.bikes} /> 

          {this.state.haveUsersLocation ? (
            <Marker position={position} icon={myIcon}>
              <Popup>Your current location</Popup>
            </Marker>
          ) : (
            ""
          )}
        </Map>
      </div>
    );
  }
}
1

1 Answers

1
votes

The reason Marker component never gets called because this.state.haveUsersLocation is always false and you are not setting it to true anywhere in the component. If you want to render Marker component only when haveUsersLocation is true then you need to change haveUsersLocation to true to render Marker otherwise remove the condition

You need to make haveUsersLocation it to true in componentWillMount and Marker will render successfully

componentWillMount() {
    fetch(
      "https://bikewise.org:443/api/v2/locations/markers?proximity_square=10"
    )
      .then(response => response.json())
      .then(response => this.setState({ haveUsersLocation: true, bikes: response.data.features }));
  }

To force react to re-render the GeoJSON data you need to pass some data-uniq key to component. Check below github issue for more details

   <GeoJSON key={`geojson-01`} addData={this.state.bikes} /> 

https://github.com/PaulLeCam/react-leaflet/issues/332#issuecomment-304228071

Also a unique key needs to be added for Marker as well

   {this.state.haveUsersLocation ? (
        <Marker key={`marker-01`} position={position} icon={myIcon}>
          <Popup>Your current location</Popup>
        </Marker>
      ) :  ""}