Capture attribute values from a WebMap without click event

1050
4
Jump to solution
11-10-2017 10:58 AM
LA
by
New Contributor

Hi,
I have a general question about how to capture attribute values from a WebMap (using API 4.x) without using click events on the map (this thread #Capture attribute values from a WebMap has an excellent solution using the click event and the hitTest method, but now I need to access attribute values without having to click on the map).

This thread #Access ArcGIS Server database content from JavaScript application has a solution based on QueryTask (API 3.22), but I don't know what this object maps to in API 4.4.

I am also not aware of having access to a REST service associated with this WebMap, and I am not familiar with the ArcGIS framework, but if I have access to a WebMap through the portalItem property, does that mean that I should get access to a REST service too? Is there a way I can access the attribute values without setting up a REST service?

I would also like to avoid using the FeatureLayer object since my web application resides in a different domain than the ArcGIS server and when I try to use FeatureLayer I get a CORS error.

I apologize for the vagueness but thanks for your help,

LA

I am also a bit confused why 

console.log("Num WebMap Layers: "+webmap.layers.length);

displays zero for number of WebMap layers, I guess they are embedded differently into the WebMap?

My current code:

require([
 "esri/views/MapView",
 "esri/WebMap",
 "dojo/domReady!"
 ], function(MapView, WebMap) {
/************************************************************
 * Creates a new WebMap instance. A WebMap must reference
 * a PortalItem ID that represents a WebMap saved to
 * arcgis.com or an on-premise portal.
 ************************************************************/
 var webmap = new WebMap({
 portalItem: { // autocasts as new PortalItem()
 id: "7faf8d05df114f8082411414382c69d3"
 //id: "65de4dd5bbfb4c0dbac85d395052bee3" // Speed Studies Web Map
 }
 });
/************************************************************
 * Set the WebMap instance to the map property in a MapView.
 ************************************************************/
 var view = new MapView({
 map: webmap,
 container: "viewMap"
 });
view.on("click", function(event) { 
 view.hitTest(event).then(function(evt){
 if(evt.results){
 console.log(evt.results[0].graphic.attributes["Type"]);
 console.log(evt.results[0].graphic.geometry);
 if(evt.results[0].graphic.attributes["Type"]!="B"){
 $("#startPt").css("background-color","red");
 }
 else{
 $("#startPt").css("background-color","transparent");
 }
 }
 });
 });
 });
 </script>
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

L A,

  So You have a lot of questions here and the easiest way to answer them all is with a sample that shows how.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Load a basic WebMap - 4.5</title>

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

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

  <script src="https://js.arcgis.com/4.5/"></script>

  <script>
    require([
      "esri/views/MapView",
      "esri/WebMap",
      "esri/tasks/support/Query",
      "dojo/domReady!"
    ], function(
      MapView, WebMap, Query
    ) {

      /************************************************************
       * Creates a new WebMap instance. A WebMap must reference
       * a PortalItem ID that represents a WebMap saved to
       * arcgis.com or an on-premise portal.
       *
       * To load a WebMap from an on-premise portal, set the portal
       * url with esriConfig.portalUrl.
       ************************************************************/
      var webmap = new WebMap({
        portalItem: { // autocasts as new PortalItem()
          id: "f2e9b762544945f390ca4ac3671cfa72"
        }
      });

      /************************************************************
       * Set the WebMap instance to the map property in a MapView.
       ************************************************************/
      var view = new MapView({
        map: webmap,
        container: "viewDiv"
      });

      webmap.then(function(){
        var query = new Query();
        query.where = '1=1';
        query.outSpatialReference = view.spatialReference;
        query.outFields = ["*"];
        webmap.layers.map(function(lyr){
          lyr.queryFeatures(query).then(function(results){
            console.info(results);
          });
        });
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>

</html>

The reason that webmap.layers.length was 0 is that you were not waiting for the webmap to initialize (line 55 above).

The above sample waits for the webmap then loops though the layers and performs a query on each layer to return all the features in that layer and console log them. So this is how you work with layer in a web map. Also if you console log the layer you will see a property called url which is the url of the layer that you could use to Query the layer using the QueryTask, but as a FeatureLayer has a queryFeatures method it is just easier to do it as above.

View solution in original post

4 Replies
RobertScheitlin__GISP
MVP Emeritus

L A,

  So You have a lot of questions here and the easiest way to answer them all is with a sample that shows how.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Load a basic WebMap - 4.5</title>

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

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

  <script src="https://js.arcgis.com/4.5/"></script>

  <script>
    require([
      "esri/views/MapView",
      "esri/WebMap",
      "esri/tasks/support/Query",
      "dojo/domReady!"
    ], function(
      MapView, WebMap, Query
    ) {

      /************************************************************
       * Creates a new WebMap instance. A WebMap must reference
       * a PortalItem ID that represents a WebMap saved to
       * arcgis.com or an on-premise portal.
       *
       * To load a WebMap from an on-premise portal, set the portal
       * url with esriConfig.portalUrl.
       ************************************************************/
      var webmap = new WebMap({
        portalItem: { // autocasts as new PortalItem()
          id: "f2e9b762544945f390ca4ac3671cfa72"
        }
      });

      /************************************************************
       * Set the WebMap instance to the map property in a MapView.
       ************************************************************/
      var view = new MapView({
        map: webmap,
        container: "viewDiv"
      });

      webmap.then(function(){
        var query = new Query();
        query.where = '1=1';
        query.outSpatialReference = view.spatialReference;
        query.outFields = ["*"];
        webmap.layers.map(function(lyr){
          lyr.queryFeatures(query).then(function(results){
            console.info(results);
          });
        });
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>

</html>

The reason that webmap.layers.length was 0 is that you were not waiting for the webmap to initialize (line 55 above).

The above sample waits for the webmap then loops though the layers and performs a query on each layer to return all the features in that layer and console log them. So this is how you work with layer in a web map. Also if you console log the layer you will see a property called url which is the url of the layer that you could use to Query the layer using the QueryTask, but as a FeatureLayer has a queryFeatures method it is just easier to do it as above.

LA
by
New Contributor

Robert,

This makes sense, thanks so much!

0 Kudos
LA
by
New Contributor

Robert,

I experimented with your code and I believe I have a grasp on how to use queries on a FeatureLayer:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
 <title>Load a basic WebMap - 4.5</title>
<style>
 html,
 body,
 #viewDiv {
 padding: 0;
 margin: 0;
 height: 100%;
 width: 100%;
 }
 </style>
<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
<script src="https://js.arcgis.com/4.5/"></script>
<script>
 require([
 "esri/views/MapView",
 "esri/WebMap",
 "esri/tasks/support/Query",
 "dojo/domReady!"
 ], function(
 MapView, WebMap, Query
 ) {
/************************************************************
 * Creates a new WebMap instance. A WebMap must reference
 * a PortalItem ID that represents a WebMap saved to
 * arcgis.com or an on-premise portal.
 *
 * To load a WebMap from an on-premise portal, set the portal
 * url with esriConfig.portalUrl.
 ************************************************************/
 var webmap = new WebMap({
 portalItem: { // autocasts as new PortalItem()
 id: "f2e9b762544945f390ca4ac3671cfa72"
 }
 });
/************************************************************
 * Set the WebMap instance to the map property in a MapView.
 ************************************************************/
 var view = new MapView({
 map: webmap,
 container: "viewDiv"
 });
webmap.then(function(){
 var query = new Query(); 
 query.where = "Population BETWEEN 0 AND 80000000";
 query.outSpatialReference = view.spatialReference;
 query.outFields = ["ST"];
 webmap.layers.map(function(lyr){
 lyr.queryFeatures(query).then(function(results){
 console.info("States with less than 80M Accidental Deaths:")
 for (var i = 0; i < results.features.length; i++){
 console.info(i + ": " + results.features[i].attributes.ST);
 }
 });
 });
 });
 });
 </script>
</head>
<body>
 <div id="viewDiv"></div>
</body>
</html>

However, when I change the WebMap id to the one my application uses, I get no results on the console. Even when I use the SQL where clause "1=1" and outFields = ["*"]:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
 <title>Load a basic WebMap - 4.5</title>
<style>
 html,
 body,
 #viewDiv {
 padding: 0;
 margin: 0;
 height: 100%;
 width: 100%;
 }
 </style>
<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
<script src="https://js.arcgis.com/4.5/"></script>
<script>
 require([
 "esri/views/MapView",
 "esri/WebMap",
 "esri/tasks/support/Query",
 "dojo/domReady!"
 ], function(
 MapView, WebMap, Query
 ) {
/************************************************************
 * Creates a new WebMap instance. A WebMap must reference
 * a PortalItem ID that represents a WebMap saved to
 * arcgis.com or an on-premise portal.
 *
 * To load a WebMap from an on-premise portal, set the portal
 * url with esriConfig.portalUrl.
 ************************************************************/
 var webmap = new WebMap({
 portalItem: { // autocasts as new PortalItem()
 id: "7faf8d05df114f8082411414382c69d3"
 }
 });
/************************************************************
 * Set the WebMap instance to the map property in a MapView.
 ************************************************************/
 var view = new MapView({
 map: webmap,
 container: "viewDiv"
 });
webmap.then(function(){
 var query = new Query();
 query.where = "1=1";
 console.info(query.where);
 query.outSpatialReference = view.spatialReference;
 query.outFields = ["*"];
 console.info(query.outFields);
 webmap.layers.map(function(lyr){
 lyr.queryFeatures(query).then(function(results){
 console.info(results);
 });
 });
 });
 });
 </script>
</head>
<body>
 <div id="viewDiv"></div>
</body>
</html>

FeatureLayer query

At first I thought it was due to some "click" event listeners that are defined inside the webmap promise, but as you can see in the code above, even with a basic setup, console.info(results) will not return anything.

I am guessing I need to change something on the GIS server side and how the WebMap was created? I am not familiar at all with the server side GIS framework but a colleague is somewhat familiar so I can ask him to make changes. Could you point me to what I need to ask him if indeed the problem is on the server side? 

Thanks again,

L A

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

L A,

   What type of layer is that in your web map?.. It does not have a URL but it says is supports queries yet it returns no results from any query I through at it..

0 Kudos