2

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 Answer 1

1

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>
      ) :  ""}
7
  • The ternary operator updates the haveUsersLocation state and the initial marker that I create displays just fine but I can't display markers from the API.
    – Shawn
    Commented Oct 5, 2018 at 20:06
  • @Shawn I have updated my answer please give a try now Commented Oct 5, 2018 at 20:13
  • You need to set response.data.features to bikes Commented Oct 5, 2018 at 20:19
  • @Think-Twice Or, alternatively, instead of altering the response, just change the GeoJSON tag? <GeoJSON addData={this.state.bikes.features} />
    – AussieJoe
    Commented Oct 5, 2018 at 20:36
  • 1
    @AussieJoe yeah agreed that is valid too Commented Oct 5, 2018 at 20:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.