Search code examples
reactjsmapboxgeocodingmapbox-gl

Include custom geocoding results in mapbox gl as part of a react app


I'm trying to pass a function as the localGeocoder parameter of a mapbox gl geocoder instance (docs here). I want to do this as part of a react app. The geocoder and map mostly work fine, but I'm not even entering into the function I'm passing when I do geocoding searches. What have I got wrong with this setup?

I know that the localGeocoder function is supposed to return an array of geojson features in the carmen geojson format, but since I couldn't get this to work I just put a console.log() statement in the function and looking at the dev tools in the browser and it's not executing. The main parts of the component are below, but you'll need to fill in your own mapbox accessToken to get it to work. I know that mapbox has a working example of how to pass a localGeocoder function, but that doesn't use react and I think that's where I'm going wrong here so that example isn't really much help to me.

import React from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css'
import Geocoder from 'mapbox-gl-geocoder';
import 'mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'
import './map.scss';

mapboxgl.accessToken = ENTER_YOUR_MAPBOX_ACCESS_TOKEN_HERE;    
export class Map extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = {
      lng: -73.9392,
      lat: 40.8053,
      zoom: 15
    };

    this.forwardGeocoder = this.forwardGeocoder.bind(this);
  }

  forwardGeocoder(query) {
    console.log('QUERY:', query);
  }
  
  componentDidMount() {
    const map = new mapboxgl.Map({
      container: this.mapContainer,
      style: 'mapbox://styles/mapbox/streets-v11',
      center: [this.state.lng, this.state.lat],
      zoom: this.state.zoom,
      zoomAnimation: false
    });

    const geocoder = new Geocoder({
      accessToken: mapboxgl.accessToken,
      mapboxgl: mapboxgl,
      autocomplete: false,
      localGeocoder: this.forwardGeocoder,
      proximity: {longitude: this.state.lng, latitude: this.state.lat}
    })
    
    map.addControl(geocoder);
  }

  render() {
    return <div ref={el => this.mapContainer = el} className='mapContainer' />
  }
}

Solution

  • Alex,

    I did a codesandbox to you check (just need to add you API Key).

    • If you search for coffee, you will see QUERY: coffee in console.

    So, the only difference from your code to mine is:

    • mapbox-gl-geocoder import.

    You are doing like this:

    import Geocoder from 'mapbox-gl-geocoder';
    import 'mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'
    

    And I'm doing like this:

    import Geocoder from "@mapbox/mapbox-gl-geocoder";
    import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";
    

    As i don´t know how you added the mapbox-gl-geocoder package, i will describe how i did:

    I'm using yarn:

    yarn add react-map-gl-geocoder

    If you are using npm:

    npm install react-map-gl-geocoder

    After that, my package.json has this versions:

    "react": "^16.13.1",
    "mapbox-gl": "^1.3.1",
    "@mapbox/mapbox-gl-geocoder": "^4.7.0",
    

    Maybe that could be the issue. Hope it works for you.