Search code examples
reactjsmapbox-gl

"this.props" not working in my on mouseup event function in Map Component using react and mapbox-gl


Hello I'm pretty new to coding and I'm having an issue that I cannot resolve. I have a MapBox map that loads up with incident icons per lat/lon and radius. Using react I created a Map component and in the map component I added a mouseup event that grabs the lat and lot when the user clicks on the map and I want to take those values and feed them into the loadIncidentsAndRoads function which fetches the incidents api call. My problem is that this.props.incidentsActions.loadIncidentsAndRoads(metroId, tmcMetro, setCoords) is not valid within the mouseup event yet if you execute the function outside of the mouseup event it works. Im not really sure what is needed to help any answer so if you need more info please let me know and I will provide them.

    <Map
      center={center}
      zoom={zoom}
      minZoom={4}
      maxZoom={20}
      style={''}
      onStyleLoad={map => {
        map.addSource('trafficTiles', trafficTiles);
        window.map = map;
        window.addEventListener('resize', this._resizeMap.bind(null, map));
        map.addControl(new mapboxgl.FullscreenControl({container: document.querySelector('body')}), "top-right");
        map.on('mouseup', function (e) {
           const getCoords = e.lngLat.wrap();
           console.log(getCoords);
           const setCoords = [getCoords.lng, getCoords.lat];
           console.log(setCoords);
           const metroId = 140;
           const tmcMetro = 45;
           return(
   //this load Incident function does not work because of the this.props is not valid
             this.props.incidentActions.loadIncidentsAndRoads(metroId, tmcMetro, setCoords)
           );
        });
        const metroId = 140;
        const tmcMetro = 45;
   // this load Incident function works but just with hard coded values.
        this.props.incidentActions.loadIncidentsAndRoads(metroId, tmcMetro, setCoords);
      }}
      onDrag={this._onDrag}
      onMoveEnd={this._setMove.bind(this, true)}
      onMove={this._setMove.bind(this, false)}
      containerStyle={mapWrapper}>
      <ZoomControl
         style={{margin: '95px 10px'}}
         zoomDiff={1}
         onControlClick={this._onControlClick}/>
      <Source
         id="source_id"
         tileJsonSource={trafficTiles}/>
      <Layer
         id="trafficTiles"
         sourceId="source_id"
         type="raster"
         layerOptions={{
           "source-layer": "trafficTiles"
         }}
         layout={{}}
           paint={{"raster-opacity": 1.0}}/>

Solution

  • The meaning of this is not preserved once you get into a function. You can try using an arrow function, which preserves the meaning of this:

    map.on('mouseup', (e) => {
               const getCoords = e.lngLat.wrap();
               const setCoords = [getCoords.lng, getCoords.lat];
               const metroId = 140;
               const tmcMetro = 45;
    
               return(
                 this.props.incidentActions.loadIncidentsAndRoads(metroId, tmcMetro, setCoords)
               );
    
            });
    

    If that is still problematic, that means that the map.on function is not preserving the meaning of this, and you'd have to pass it another way. Earlier in your component, before your return(...), you can destructure incidentActions from your props, and use it directly:

    // before return( ... ) of the component
    const { incidentActions } = this.props
    
    //back within your <Map>
    map.on('mouseup', function (e) {
               const getCoords = e.lngLat.wrap();
               const setCoords = [getCoords.lng, getCoords.lat];
               const metroId = 140;
               const tmcMetro = 45;
    
               return(
                 incidentActions.loadIncidentsAndRoads(metroId, tmcMetro, setCoords)
               );
    
            });