Cannot access items array property of MapView.allLayerViews (ArcJS API 4.4)

766
3
Jump to solution
09-25-2017 03:47 PM
DevonCanady
New Contributor II

See below:

require(["esri/Map","esri/views/MapView"], function(Map, MapView) {    
   var map = new Map({ basemap: "streets" });     
   var view = new MapView({        
      container: "viewDiv",        
      map: map,        
      center: [-97.744483, 30.272705],        
      zoom: 15,    
}); 

console.log(view.allLayerViews.items);

console.log(view.allLayerViews.items[0]);

console.log(view.allLayerViews.length);

I suppose the array calls are accessing the Array prototype, but I don't know how to make it not do that. I would like to be able to loop through the layerViews with forEach().

0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor

You have to wait until you've added something to the view and it's ready. This is taken from this sample (adding lines 106-110)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Get started with layers - 4.4</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <script src="https://js.arcgis.com/4.4/"></script>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }

    #layerToggle {
      top: 20px;
      right: 20px;
      position: absolute;
      z-index: 99;
      background-color: white;
      border-radius: 8px;
      padding: 10px;
      opacity: 0.75;
    }
  </style>

  <script>
    require([
        "esri/Map",
        "esri/views/SceneView",
        "esri/layers/TileLayer",
        "dojo/dom",
        "dojo/on",
        "dojo/domReady!"
      ],
      function(
        Map, SceneView, TileLayer, dom, on
      ) {

        /*****************************************************************
         * Create two TileLayer instances. One pointing to a
         * cached map service depicting U.S. male population and the other
         * pointing to a layer of roads and highways.
         *****************************************************************/
        var transportationLyr = new TileLayer({
          url: "https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer",
          // This property can be used to uniquely identify the layer
          id: "streets",
          visible: false
        });

        var housingLyr = new TileLayer({
          url: "https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Housing_Density/MapSer...",
          id: "ny-housing",
          opacity: 0.9
        });

        /*****************************************************************
         * Layers may be added to the map in the map's constructor
         *****************************************************************/
        var map = new Map({
          basemap: "oceans",
          layers: [housingLyr]
        });

        /*****************************************************************
         * Or they may be added to the map using map.add()
         *****************************************************************/
        map.add(transportationLyr);

        var view = new SceneView({
          container: "viewDiv",
          map: map
        });

        /*****************************************************************
         * The map handles the layers' data while the view and layer views
         * take care of renderering the layers
         *****************************************************************/
        view.on("layerview-create", function(event) {
          if (event.layer.id === "ny-housing") {
            // Explore the properties of the population layer's layer view here
            console.log("LayerView for male population created!", event.layerView);
          }
          if (event.layer.id === "streets") {
            // Explore the properties of the transportation layer's layer view here
            // Explore the properties of the transportation layer's layer view here
            console.log("LayerView for streets created!", event.layerView);
          }
        });

        /*****************************************************************
         * Layers are promises that resolve when loaded, or when all their
         * properties may be accessed. Once the population layer has loaded,
         * the view will animate to it's initial extent.
         *****************************************************************/
        view.then(function() {
          housingLyr.then(function() {
            view.goTo(housingLyr.fullExtent);
            console.log(view.allLayerViews.items);
            for (var i = 0; i < view.allLayerViews.length; i++) {
              console.log(view.allLayerViews.items[i].declaredClass);
            }
          });
        });

        var streetsLyrToggle = dom.byId("streetsLyr");

        /*****************************************************************
         * The visible property on the layer can be used to toggle the
         * layer's visibility in the view. When the visibility is turned off
         * the layer is still part of the map, which means you can access
         * its properties and perform analysis even though it isn't visible.
         *******************************************************************/
        on(streetsLyrToggle, "change", function() {
          transportationLyr.visible = streetsLyrToggle.checked;
        });
      });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <span id="layerToggle">
    <input type="checkbox" id="streetsLyr"> Transportation
  </span>
</body>

</html>

View solution in original post

3 Replies
RobertScheitlin__GISP
MVP Emeritus

Devon,

   Based on you shared code you only have a basemap added to the view and no other layers so the allLayerViews collection would be empty.

0 Kudos
KenBuja
MVP Esteemed Contributor

You have to wait until you've added something to the view and it's ready. This is taken from this sample (adding lines 106-110)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Get started with layers - 4.4</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <script src="https://js.arcgis.com/4.4/"></script>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }

    #layerToggle {
      top: 20px;
      right: 20px;
      position: absolute;
      z-index: 99;
      background-color: white;
      border-radius: 8px;
      padding: 10px;
      opacity: 0.75;
    }
  </style>

  <script>
    require([
        "esri/Map",
        "esri/views/SceneView",
        "esri/layers/TileLayer",
        "dojo/dom",
        "dojo/on",
        "dojo/domReady!"
      ],
      function(
        Map, SceneView, TileLayer, dom, on
      ) {

        /*****************************************************************
         * Create two TileLayer instances. One pointing to a
         * cached map service depicting U.S. male population and the other
         * pointing to a layer of roads and highways.
         *****************************************************************/
        var transportationLyr = new TileLayer({
          url: "https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer",
          // This property can be used to uniquely identify the layer
          id: "streets",
          visible: false
        });

        var housingLyr = new TileLayer({
          url: "https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Housing_Density/MapSer...",
          id: "ny-housing",
          opacity: 0.9
        });

        /*****************************************************************
         * Layers may be added to the map in the map's constructor
         *****************************************************************/
        var map = new Map({
          basemap: "oceans",
          layers: [housingLyr]
        });

        /*****************************************************************
         * Or they may be added to the map using map.add()
         *****************************************************************/
        map.add(transportationLyr);

        var view = new SceneView({
          container: "viewDiv",
          map: map
        });

        /*****************************************************************
         * The map handles the layers' data while the view and layer views
         * take care of renderering the layers
         *****************************************************************/
        view.on("layerview-create", function(event) {
          if (event.layer.id === "ny-housing") {
            // Explore the properties of the population layer's layer view here
            console.log("LayerView for male population created!", event.layerView);
          }
          if (event.layer.id === "streets") {
            // Explore the properties of the transportation layer's layer view here
            // Explore the properties of the transportation layer's layer view here
            console.log("LayerView for streets created!", event.layerView);
          }
        });

        /*****************************************************************
         * Layers are promises that resolve when loaded, or when all their
         * properties may be accessed. Once the population layer has loaded,
         * the view will animate to it's initial extent.
         *****************************************************************/
        view.then(function() {
          housingLyr.then(function() {
            view.goTo(housingLyr.fullExtent);
            console.log(view.allLayerViews.items);
            for (var i = 0; i < view.allLayerViews.length; i++) {
              console.log(view.allLayerViews.items[i].declaredClass);
            }
          });
        });

        var streetsLyrToggle = dom.byId("streetsLyr");

        /*****************************************************************
         * The visible property on the layer can be used to toggle the
         * layer's visibility in the view. When the visibility is turned off
         * the layer is still part of the map, which means you can access
         * its properties and perform analysis even though it isn't visible.
         *******************************************************************/
        on(streetsLyrToggle, "change", function() {
          transportationLyr.visible = streetsLyrToggle.checked;
        });
      });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <span id="layerToggle">
    <input type="checkbox" id="streetsLyr"> Transportation
  </span>
</body>

</html>
DevonCanady
New Contributor II

I tried to only include the pertinent code since it's a snippet of a larger file but I failed to include the lines where I added my layers to the map. But Ken you are correct. Embedding the layer.then() inside the view.then() allows me to access the items array of view.allLayerViews. Thanks!

0 Kudos