SamSamskies / react-map-gl-geocoder

React wrapper for mapbox-gl-geocoder for use with react-map-gl
MIT License
123 stars 29 forks source link

TypeError: Cannot read property 'remove' of undefined __ Cannot read property 'addControl' of null - #98

Closed LAYTHJABBAR closed 3 years ago

LAYTHJABBAR commented 3 years ago

Adding Gecoder to the Map causing a lot of error messages

my component is `import './map.scss'; import React, { useRef } from 'react'; import mapboxgl from 'mapbox-gl'; import ReactMapGL, { Marker, Source, layer } from 'react-map-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; import 'react-map-gl-geocoder/dist/mapbox-gl-geocoder.css'; import Geocoder from 'react-map-gl-geocoder'; import clsx from 'clsx'; import PropTypes from 'prop-types'; import DropoffPinWithLayer from '../../pages/Routing/Components/Pins/dropoffWithLayer'

const Map = (props) => { let ZoomCustomer, MarkeAllCustomers, GeocoderTag, SearchBarRefrence; const geocoderContainerRef = React.useRef(); const mapRef = useRef();

if(props.isSearchOutOfMap === true) { SearchBarRefrence = (

); }

if (props.geocoder == true) { GeocoderTag = ( <Geocoder containerRef={geocoderContainerRef} mapRef={mapRef} onViewportChange={props.handleGeocoderViewportChange} mapboxApiAccessToken={mapboxgl.accessToken} position={props.position} onResult={props.handleOnResult} ReverseGeoCode={true} onClear={props.handleOnClear} /> ); } if (props.customerToZoom == true) { ZoomCustomer = (

{props.marker}
);

} if (props.customerToZoom == true && props.itsDraggable === true) {

ZoomCustomer = (
  <DropoffPinWithLayer
    location={ props.customerToMark }
    onDragEnd={props.handleOnDragEnd}
    radius={props.radius}
  />
);

}

if (props.markCustomers == true) { let customers = props.customers; MarkeAllCustomers = customers.map((customer) => { const { lon, lat, uuid } = customer; if (props.customerArr) { return (

props.mouseDown(customer)} />
    );
  } else if (props.selcustomers) {
    return (
      <Marker key={uuid} longitude={lon} latitude={lat}>
        <i
          type="button"
          className={clsx(props.styles.pin, { [props.styles.selected]: customer.name === props.selCustomer })}
          onMouseDown={() => props.mouseDown(customer.name)}
        />
      </Marker>
    );
  }
});

}

return (

{SearchBarRefrence} { props.handleOnClickEnd(event) }} height={props.height} onViewportChange={props.handleViewportChange} mapboxApiAccessToken={mapboxgl.accessToken} mapStyle="mapbox://styles/mapbox/outdoors-v11" > {ZoomCustomer} {MarkeAllCustomers} {GeocoderTag}

); };

Map.propTypes = { width: PropTypes.string, onViewportChange: PropTypes.func, mapboxApiAccessToken: PropTypes.string, onResult: PropTypes.func, onClear: PropTypes.func, position: PropTypes.string, itsDraggable: PropTypes.bool, handleOnDragEnd: PropTypes.func, radius: PropTypes.number, height: PropTypes.string, handleOnClickEnd: PropTypes.func, };

Map.defaultProps = { width: '100px', handleOnClickEnd: (event) => {console.log(event)}, handleOnDragEnd: () => {}, onViewportChange: () => {}, onResult: () => {}, onClear: () => {}, mapboxApiAccessToken: '', position: 'top-left', itsDraggable: false, radius: 0, height: "220px" };

export default Map;`

the error messages :

× ←→1 of 2 errors on the page TypeError: Cannot read property 'remove' of undefined Gt.off C:/Users/Layth-Doppl/Desktop/Doppl/node_modules/@mapbox/mapbox-gl-geocoder/lib/index.js:858 855 | off: function(type, fn) { 856 | this._eventEmitter.removeListener(type, fn); 857 | this.eventManager.remove();

858 | return this; 859 | } 860 | }; 861 | View compiled i.e.unsubscribeEvents C:/Users/Layth-Doppl/Desktop/Doppl/src/index.js:135 i.e.removeGeocoder C:/Users/Layth-Doppl/Desktop/Doppl/src/index.js:145 i.o.componentWillUnmount C:/Users/Layth-Doppl/Desktop/Doppl/src/index.js:18 15 | let result = null; 16 | if (subject.length * clipping.length === 0) { 17 | if (operation === INTERSECTION) { 18 | result = EMPTY; | ^ 19 | } else if (operation === DIFFERENCE) { 20 | result = subject; 21 | } else if (operation === UNION || View compiled ▶ 29 stack frames were collapsed. ResizeObserver. C:/Users/Layth-Doppl/src/components/static-map.js:163 160 | const resizeObserver = new ResizeObserver(entries => { 161 | if (entries[0].contentRect) { 162 | const {width, height} = entries[0].contentRect; 163 | setSize([width, height]); | ^ 164 | props.onResize({width, height}); 165 | } 166 | }); View compiled

TypeError: Cannot read property 'addControl' of null i.e.initializeGeocoder C:/Users/Layth-Doppl/Desktop/Doppl/src/index.js:79 76 | const contours = connectEdges(sortedEvents, operation); 77 | //console.timeEnd('connect vertices'); 78 |

79 | // Convert contours to polygons | ^ 80 | const polygons = []; 81 | for (let i = 0; i < contours.length; i++) { 82 | let contour = contours[i]; View compiled i.o.componentDidMount C:/Users/Layth-Doppl/Desktop/Doppl/src/index.js:14 11 | const EMPTY = []; 12 | 13 | 14 | function trivialOperation(subject, clipping, operation) { 15 | let result = null; 16 | if (subject.length * clipping.length === 0) { 17 | if (operation === INTERSECTION) { View compiled ▶ 18 stack frames were collapsed. ResizeObserver. C:/Users/Layth-Doppl/src/components/static-map.js:163 160 | const resizeObserver = new ResizeObserver(entries => { 161 | if (entries[0].contentRect) { 162 | const {width, height} = entries[0].contentRect; 163 | setSize([width, height]); | ^ 164 | props.onResize({width, height}); 165 | } 166 | });

SamSamskies commented 3 years ago

Hi @LAYTHJABBAR, I think you may be missing some code. I don't see where your Geocoder component is being rendered. I can't really help debug without seeing how you're rendering that component. It would help if you provide a Code Sandbox demonstrating the issue.

You can also check out this closed issue https://github.com/SamSamskies/react-map-gl-geocoder/issues/56.

LAYTHJABBAR commented 3 years ago

Hi @SamSamskies thank you for your response, the Gecoder is rendering on GeocoderTag

import './map.scss';
import React, { useRef } from 'react';
import mapboxgl from 'mapbox-gl';
import ReactMapGL, { Marker, Source, layer } from 'react-map-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import 'react-map-gl-geocoder/dist/mapbox-gl-geocoder.css';
import Geocoder from 'react-map-gl-geocoder';
import clsx from 'clsx';
import PropTypes from 'prop-types';
import DropoffPinWithLayer  from '../../pages/Routing/Components/Pins/dropoffWithLayer'

const Map = (props) => {
  let ZoomCustomer, MarkAllCustomers, GeocoderTag, SearchBarRefrence;
  const geocoderContainerRef = React.useRef();
  const mapRef = useRef();

   if(props.isSearchOutOfMap === true) {
    SearchBarRefrence = (<div ref={geocoderContainerRef} />);
   }

  if (props.geocoder == true) {
    GeocoderTag = (
      <Geocoder
        containerRef={geocoderContainerRef}
        mapRef={mapRef}
        onViewportChange={props.handleGeocoderViewportChange}
        mapboxApiAccessToken={mapboxgl.accessToken}
        position={props.position}
        onResult={props.handleOnResult}
        ReverseGeoCode={true}
        onClear={props.handleOnClear}
      />
    );
  }
  if (props.customerToZoom == true) {
    ZoomCustomer = (
      <Marker latitude={props.customerToMark.lat} longitude={props.customerToMark.lon} >
        {props.marker}
      </Marker>
    );
  }
  if (props.customerToZoom == true && props.itsDraggable === true) {

    ZoomCustomer = (
      <DropoffPinWithLayer
        location={ props.customerToMark }
        onDragEnd={props.handleOnDragEnd}
        radius={props.radius}
      />
    );
  }

  if (props.markCustomers == true) {
    let customers = props.customers;
    MarkAllCustomers = customers.map((customer) => {
      const { lon, lat, uuid } = customer;
      if (props.customerArr) {
        return (
          <Marker key={uuid} longitude={lon} latitude={lat}>
            <i
              type="button"
              className={clsx(props.styles.pin, { [props.styles.selected]: props.customerArr.includes(customer) })}
              onMouseDown={() => props.mouseDown(customer)}
            />
          </Marker>
        );
      } else if (props.selcustomers) {
        return (
          <Marker key={uuid} longitude={lon} latitude={lat}>
            <i
              type="button"
              className={clsx(props.styles.pin, { [props.styles.selected]: customer.name === props.selCustomer })}
              onMouseDown={() => props.mouseDown(customer.name)}
            />
          </Marker>
        );
      }
    });
  }

  return (
    <div>
  {SearchBarRefrence}
    <ReactMapGL
      {...props.viewport}
      ref={mapRef}
      width={props.width}
      onClick={(event) => {
        props.handleOnClickEnd(event)
      }}
      height={props.height}
      onViewportChange={props.handleViewportChange}
      mapboxApiAccessToken={mapboxgl.accessToken}
      mapStyle="mapbox://styles/mapbox/outdoors-v11"
      >
      {ZoomCustomer}
      {MarkAllCustomers}
      {GeocoderTag}
    </ReactMapGL>

    </div>
  );
};

Map.propTypes = {
  width: PropTypes.string,
  onViewportChange: PropTypes.func,
  mapboxApiAccessToken: PropTypes.string,
  onResult: PropTypes.func,
  onClear: PropTypes.func,
  position: PropTypes.string,
  itsDraggable: PropTypes.bool,
  handleOnDragEnd: PropTypes.func,
  radius: PropTypes.number,
  height: PropTypes.string,
  handleOnClickEnd: PropTypes.func,
};

Map.defaultProps = {
  width: '100px',
  handleOnClickEnd: (event) => {console.log(event)},
  handleOnDragEnd: () => {},
  onViewportChange: () => {},
  onResult: () => {},
  onClear: () => {},
  mapboxApiAccessToken: '',
  position: 'top-left',
  itsDraggable: false,
  radius: 0,
  height: "220px"
};

export default Map;
SamSamskies commented 3 years ago

It looks like you're conditionally rendering the geocoder container. The problem could be that you're rendering the Geocoder and not rendering SearchBarRefrence which would probably cause the errors that you're having. Try removing the containerRef prop to verify.

Another issue that I see is that there is no prop called ReverseGeoCode. I think you want reverseGeocode.

Also, make sure all of the Geocoder props that are objects or functions are memoized. You're passing in a bunch of the props from a parent component, and I'm not sure if you're memoizing the values or not.

Matt-Vance commented 3 years ago

FYI I had a similar issue when upgrading to react-map-gl@5.3.0. Downgraded back to @5.2.3 and the geocoder now works.

daniela-green commented 3 years ago

@Matt-Vance exactly what happened to me. Downgrading to react-map-gl @5.2.3 solved it.

LAYTHJABBAR commented 3 years ago

Thanks @Matt-Vance the issue got solved by downgrading react-map-gl to @5.2.3