Select to view content in your preferred language

Get fields from featureLayer created from rest service?

4280
12
Jump to solution
12-04-2019 11:35 AM
VincentLantaca1
Occasional Contributor

I am trying to figure out a good way to retrieve the fields from an ArcGIS REST service. I first create a FeatureLayer from the a feature server url. When I console.log the feature layer, I see that it has fields, but when I try to console.log(featureLayer.fields) it is just null.

I need the field information to create a popup template, but I am trying to find a way to avoid having to hard-code the field information. What is a good way of going about this? 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }
    </style>
    <link rel="stylesheet" href="https://js.arcgis.com/4.13/esri/css/main.css">
    <script src="https://js.arcgis.com/4.13/"></script>
</head>
<body>
<div id="viewDiv"></div>
<script>
    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/widgets/Legend",
        "esri/PopupTemplate",
        "esri/layers/FeatureLayer",
        "esri/Graphic"
    ], function(Map, MapView, Legend, PopupTemplate, FeatureLayer, Graphic){

        var map = new Map({
            basemap: "gray"
        });

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

        var featureLayer = new FeatureLayer({
            url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/earthquakes_geojson/FeatureServer/0"
        });

        console.log(featureLayer);
        console.log(featureLayer.fields);

        // add the layer to the map
        map.add(featureLayer);
    });
</script>
</body>
</html>
0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor

You have to wait until the feature layer is ready. You're trying to access its information before it's been created.

featureLayer.when(() => {
  console.log(featureLayer);
  console.log(featureLayer.fields);
});‍‍‍‍

View solution in original post

12 Replies
KenBuja
MVP Esteemed Contributor

You have to wait until the feature layer is ready. You're trying to access its information before it's been created.

featureLayer.when(() => {
  console.log(featureLayer);
  console.log(featureLayer.fields);
});‍‍‍‍
diaconori
Occasional Contributor

when doesn't exist on the featureLayer. I am getting an error whenever it is about to fire. 

0 Kudos
JohnGrayson
Esri Regular Contributor

Try to ensure the layer is loaded:

featureLayer.load().then(() => {
  console.log(featureLayer.title, featureLayer.fields);
});

 

0 Kudos
diaconori
Occasional Contributor

Doesn't work. I am getting the following error:

 

TypeError: featureLayer.load is not a function
at dno_presenter.js?wab_dv=2.20:217
at LayerNode.js?wab_dv=2.20:127
at Object.traversal (LayerInfo.js?wab_dv=2.20:156)
at Object.traversal (LayerNode.js?wab_dv=2.20:126)
at Object._traversal (LayerStructure.js?wab_dv=2.20:124)
at Object.traversal (LayerStructure.js?wab_dv=2.20:146)
at Object.initLayers (dno_presenter.js?wab_dv=2.20:212)
at Object.initializeLayersWithFields (dno_presenter.js?wab_dv=2.20:494)
at Object.initComponents (dno_presenter.js?wab_dv=2.20:80)
at Object.initPresenter (Widget.js?wab_dv=2.20:22)

 

Code:

 

this.layerStructure.traversal((layerNode) => {
                        console.log("layerNode", layerNode);
                        let featureLayerUrl = layerNode?._layerInfo?.layerObject?.url;
                        let featureLayer = new FeatureLayer(featureLayerUrl);
                        console.log("featureLayer", featureLayer);
                        featureLayer.when(() => {
                            console.log(featureLayer);
                            console.log(featureLayer.fields);
                        });
                    }

 

 

0 Kudos
diaconori
Occasional Contributor

This shouldn't be accepted answer. I am getting the following exception:

TypeError: featureLayer.when is not a function
    at dno_presenter.js?wab_dv=2.20:217
    at LayerNode.js?wab_dv=2.20:127
    at Object.traversal (LayerInfo.js?wab_dv=2.20:156)
    at Object.traversal (LayerNode.js?wab_dv=2.20:126)
    at Object._traversal (LayerStructure.js?wab_dv=2.20:124)
    at Object.traversal (LayerStructure.js?wab_dv=2.20:146)
    at Object.initLayers (dno_presenter.js?wab_dv=2.20:212)
    at Object.initializeLayersWithFields (dno_presenter.js?wab_dv=2.20:495)
    at Object.initComponents (dno_presenter.js?wab_dv=2.20:80)
    at Object.initPresenter (Widget.js?wab_dv=2.20:22)

Code:

this.layerStructure.traversal((layerNode) => {
                        console.log("layerNode", layerNode);
                        let featureLayerUrl = layerNode?._layerInfo?.layerObject?.url;
                        let featureLayer = new FeatureLayer(featureLayerUrl);
                        console.log("featureLayer", featureLayer);
                        featureLayer.when(() => {
                            console.log(featureLayer);
                            console.log(featureLayer.fields);
                        });
                    }

 

0 Kudos
JohnGrayson
Esri Regular Contributor

Q: did you try my suggestion of waiting for the layer to loaded first?

featureLayer.load().then(() => {
  console.log(featureLayer.title, featureLayer.fields);
});

 

0 Kudos
diaconori
Occasional Contributor

Yes, both load() and then() and when() are methods that other developers including you have suggested but the console spits out an error messaging saying that those doesn't exist on the featureLayer. When I log out the featureLayer to the console, I can see that there is a property called _fields of the type Proxy. If the web map retrieves layers from a FeatureServer REST service, I am able to fetch the _fields property and deconstruct the Proxy object, however, if it is a layer from a MapServer REST service, it is not possible. 

We're running our GIS on an ArcGIS Enterprise. 

My thread: https://community.esri.com/t5/arcgis-web-appbuilder-questions/fetch-proxy-object-fields-from-feature...

0 Kudos
JohnGrayson
Esri Regular Contributor

Q: do you have a very simple codepen (or similar) so we can experience the issue?

0 Kudos
diaconori
Occasional Contributor

 

 

this.layerStructure.traversal((layerNode) => {
                        let layerServiceUrl = layerNode?._layerInfo?.layerObject?.url;
                        let featureLayer = new FeatureLayer(layerServiceUrl);
// your suggestion
}

 

I have implemented your suggestion on line 4, but it throws an error saying that load, then and when doesn't exist. I checked the docs, and they aren't listed there: https://developers.arcgis.com/javascript/3/jsapi/featurelayer-amd.html

Access to the layers of the map through LayerStructure: https://developers.arcgis.com/web-appbuilder/api-reference/layerstructure.htm

"jimu/LayerStructure",

You can paste the code in your postCreate method, after importing the above in your AMD.  Your web map needs to import an ArcGIS REST Service of the type: MapServer, as rest services of the type FeatureServer can provide _fields through a proxy object:

diaconori_0-1629992408344.png

Not sure if it is different on a plain webpage that you're calling the ArcGIS JavaScript API from, but it seems to be vastly different when you're running WAB on ArcGIS Enterprise. 
Where to import on your web map:

diaconori_1-1629992532474.png

 

0 Kudos