mapbox-gl-js icon indicating copy to clipboard operation
mapbox-gl-js copied to clipboard

getStyle() throws an TypeError. Cannot read properties of undefined (reading 'version')

Open anna-visarsoft opened this issue 1 year ago • 2 comments

mapbox-gl-js version: 2.9.1

browser: Google Chrome Version 104.0.5112.101 (x86_64)

Steps to Trigger Behavior

My goal is to create a custom control for switching between map styles.

  1. I get this error when I am trying to create a new iControl.
  onAdd(map) {
    this._map = map;

    this._btn = document.createElement('button');
    this._btn.className = 'mapboxgl-ctrl-icon mapboxgl-ctrl-styletoggle';
    this._btn.type = 'button';
    this._btn['aria-label'] = 'Toggle Style';

    **const currentStyle = this._map.getStyle();**
    
    this._container = document.createElement('div');
    this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group mb-3';
    this._container.appendChild(this._btn);

    return this._container;
  }
  1. I get this error when I call getStyle in the useControl as well
export default function StyleSwitcherControl(props) {
  useControl((mapgl) => {
      **const currentStyle = mapgl.map.getStyle();**
      const styleSwitcher = new StyleSwitcher({
        ...props,
      });
      return styleSwitcher;
    },
    {
      position: props.position
    }
  );

Expected Behavior

To get the object:

{
    "version": 8,
    "name": "Mapbox Satellite",
    "metadata": {
        "mapbox:autocomposite": true,
        "mapbox:type": "default"
    },
    "center": [ 0, 0 ],
    "zoom": 3,
    "sprite": "mapbox://sprites/mapbox/satellite-v9",
    "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
    "sources": {
        "mapbox": {
            "type": "raster",
            "url": "mapbox://mapbox.satellite",
            "tileSize": 256
        }
    },
    "layers": [
        {
            "id": "background",
            "type": "background",
            "paint": {
                "background-color": "rgb(4,7,14)"
            }
        },
        {
            "id": "satellite",
            "type": "raster",
            "source": "mapbox",
            "source-layer": "mapbox_satellite_full"
        }
    ]
}

Actual Behavior

Console error:

TypeError: Cannot read properties of undefined (reading 'version')
ei.serialize
node_modules/mapbox-gl/dist/mapbox-gl.js:35

Am I doing something wrong? Thanks for response!

anna-visarsoft avatar Sep 05 '22 15:09 anna-visarsoft

Hi @anna-visarsoft, thanks for reporting this issue! To help better diagnosis the problem, we need more information to reproduce the error. Are you setting the version in your style? Are you receiving this error in another version of gl-js? Can you provide a minimal code reproduction of this issue using jsbin or codepen? Thanks!

avpeery avatar Sep 07 '22 21:09 avpeery

Hi @avpeery! I should mention that I use React with react-map-gl library. I didn't pass the version, I set style in the mapStyle prop.

      <MapGL
        ref={mapRef}
        initialViewState={{    
          longitude: center[0],
          latitude: center[1],
          zoom: 3,
          bearing: 0,
          pitch: 50,
        }}
        mapStyle="mapbox://styles/mapbox/satellite-v9"
        mapboxAccessToken={mapbox_access_token}
      >
        <StyleSwitcherControl position="bottom-left"/>
        <NavigationControl position="bottom-left"/>
      </MapGL>

I can post an example later on codesandbox.io.

anna-visarsoft avatar Sep 08 '22 07:09 anna-visarsoft

@anna-visarsoft Following up on this ticket - are you able to provide a minimal, complete, verifiable demonstration of the issue without react. We recommend using jsbin or codepen.

I am also wondering if you see this error if you hardcode longitude and latitude values?

avpeery avatar Sep 30 '22 18:09 avpeery

hi @avpeery! Unfortunately I didn't create codesandbox.io example. But it is not needed now because I have fixed this issue. It was my mistake. Adding condition if (map) in the addCustomControls function and calling this function on onLoad onLoad={addCustomControls} in the MapGL component helped.

  const addCustomControls = (event) => {
    const map = event?.target;
    if (map) {
      map.addControl(new StyleSwitcherControl({
        firstStyle: satellite_map_style,
        secondStyle: dark_map_style
      }), 'bottom-left');
    }
  }
      <MapGL
        ref={mapRef}
        initialViewState={{    
          longitude: mapPosition.center[0],
          latitude: mapPosition.center[1],
          zoom: initialZoom,
          bearing: 0,
          pitch: 50
        }}
        mapStyle={satellite_map_style}
        mapboxAccessToken={mapbox_access_token}
        onLoad={addCustomControls}
      >

anna-visarsoft avatar Oct 18 '22 14:10 anna-visarsoft