mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.06k stars 2.21k forks source link

Cannot read property 'getLayoutProperty' of undefined #8733

Open R1D3 opened 5 years ago

R1D3 commented 5 years ago

Hello ! im trying to use the example 'show and hide layers'

`var visibility = map.getLayoutProperty(clickedLayer, 'visibility');

if (visibility === 'visible') { map.setLayoutProperty(clickedLayer, 'visibility', 'none'); this.className = ''; } else { this.className = 'active'; map.setLayoutProperty(clickedLayer, 'visibility', 'visible'); } }; `

but i have this error each time i use getLayoutProperty :

Cannot read property 'getLayoutProperty' of undefined,

why ?

thanks.

mourner commented 5 years ago

Because map is undefined at the time you call it? It's impossible to tell without a live reproducible test case which was in the issue template. Anyway, this repo is meant for reporting issues, not for asking for coding help — please use StackOverflow.

puiutucutu commented 4 years ago

Hi @mourner - rather than opening a separate issue, I will piggyback and provide an example.

Edit - you can ignore this, I should have opened this bug first https://github.com/mapbox/mapbox-gl-js/issues/8654

I don't necessarily believe this is wrong behaviour, since a default of undefined implies that the layer property has never been set before. But, it would have saved some time if this was mentioned in the documentation.

mapbox-gl-js version: 1.3.1

Steps to Trigger Behavior

Call getLayoutProperty() on a layer that does not explicitly have the visibility property set on the layout properties object.

map.getLayoutProperty("layerName", "visibility")

Expected Behavior

Return the default of visible as per the docs even when the layour.visible property is not explicitly set at layer creation time.

From https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-layout

background

visibility
Layout property. Optional enum. One of "visible", "none". Defaults to "visible".
Whether this layer is displayed.

"visible":
The layer is shown.

"none":
The layer is not shown.

Actual Behavior

Returns undefined.

Example

Modified example from https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Show and hide layers</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
    <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.1/mapbox-gl.js"></script>
    <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.1/mapbox-gl.css" rel="stylesheet"/>
    <style>
      body { margin: 0; padding: 0; }
      #map { position: absolute; top: 0; bottom: 0; width: 100%; }
    </style>
  </head>
  <body>
    <div id="map"></div>

    <script>
      mapboxgl.accessToken = <TOKEN>

      var map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        zoom: 15,
        center: [-71.97722138410576, -13.517379300798098]
      });

      map.on("load", function() {
        map.addSource("museums", { type: "vector", url: "mapbox://mapbox.2opop9hr" });
        map.addSource("contours", { type: "vector", url: "mapbox://mapbox.mapbox-terrain-v2" });
        map.addLayer({
          id: "museums",
          type: "circle",
          source: "museums",
          paint: {
            "circle-radius": 8,
            "circle-color": "rgba(55,148,179,1)"
          },
          "source-layer": "museum-cusco"
        });
        map.addLayer({
          id: "contours",
          type: "line",
          source: "contours",
          "source-layer": "contour",
          layout: {
            visibility: "visible",
            "line-join": "round",
            "line-cap": "round"
          },
          paint: { "line-color": "#877b59", "line-width": 1 }
        });

        const museumsLayerVisibility = map.getLayoutProperty("museums", "visibility");
        const contoursLayerVisibility = map.getLayoutProperty("contours", "visibility");

        console.log("Museums layer visibility", museumsLayerVisibility); //=> "visible"
        console.log("Contours layer visibility", contoursLayerVisibility); //=> undefined
      });
    </script>
  </body>
</html>
Adraesh commented 9 months ago

Hello,

I confirm this issue but I am a bit surpised to see that this ticket was openned 4 years ago and it is still openned, that makes me wonder if this is still a bug or?

Thanks.

Adraesh commented 9 months ago

Problem solved on our side.

We are using a custom style and the "visibility" property must be explicitely set/defined on the style layers in order to be accessible then by the getLayoutProperty().

Thanks.