Andy Frey
Andy Frey

Reputation: 161

Adding Searchbar with leaflet-geosearch

I'm trying to add a search bar using leaflet-geosearch to my Leaflet Map in React (react-leaflet)

import { Map, TileLayer, MapControl } from 'react-leaflet'
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch'

class Search extends MapControl {
  createLeafletElement() {
    return GeoSearchControl({
      provider: new OpenStreetMapProvider(),
      style: 'bar'
    })
  }
}

...

export class MapContainer extends Component {
  render() {
    return (
      <div>
        <Map
          ref={m => { this.leafletMap = m; }}
          center={this.state.position}
          zoom={this.state.zoom}
        >
          <TileLayer
            attribution={tilesAttr}
            url={tilesUrl}
          />
          <Search />
        </Map>
      </div>
    )
  }
}

When I run this I get a TypeError:

TypeError: Cannot read property 'map' of undefined Search.componentDidMount

};

MapControl.prototype.componentDidMount = function componentDidMount() {
-> this.leafletElement.addTo(this.props.leaflet.map);
};

MapControl.prototype.componentDidUpdate = function componentDidUpdate(prevProps) {

Has anyone had success adding a search bar to their leaflet map?

Upvotes: 0

Views: 6860

Answers (3)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59358

The list of changes:

  • wrap your component with withLeaflet HOC to ensure the control is getting initialized once the map is loaded, for example export default withLeaflet(GeoSearch);
  • control needs to be added into map explicitly, for example in componentDidMount function
  • leaflet-geosearch css needs to be referenced, for example via public/index.html

Example

class Search extends MapControl {

  createLeafletElement(opts) {
    const provider = new OpenStreetMapProvider();
    const searchControl = new GeoSearchControl({
      provider: provider,
      //position: "topleft",
      style: "bar"
    });

    return searchControl;
  }

  componentDidMount() {
    const { map } = this.props.leaflet;
    map.addControl(this.leafletElement);
  }
}

Here is a demo

Upvotes: 1

paulzmuda
paulzmuda

Reputation: 181

Use "withLeaflet"

answer here https://github.com/smeijer/leaflet-geosearch/issues/167#issuecomment-403107336

and here https://react-leaflet.js.org/docs/en/custom-components.html

*import ...unrelated imports*
import { Map, TileLayer, Marker, MapControl, Popup, ZoomControl, withLeaflet } from 'react-leaflet';
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';

class SearchMap extends MapControl {

    createLeafletElement() {
      return GeoSearchControl({
        provider: new OpenStreetMapProvider(),
        style: 'bar',
        showMarker: true,
        showPopup: false,
        autoClose: true,
        retainZoomLevel: false,
        animateZoom: true,
        keepResult: false,
        searchLabel: 'search'
      });
    }
}


class MapContainer extends React.Component {
  render() {
    const SearchBar = withLeaflet(SearchMap);  {/*  this part is needed */}
    return(
      <Map>
        <SearchBar />
        {/* rest of your map elements */}
      </Map>
    );
  }
}

export default MapContainer;

Upvotes: 1

Eugene Silchenko
Eugene Silchenko

Reputation: 11


const GeoSearch = withLeaflet(Search)


Upvotes: 1

Related Questions