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>
Solved! Go to Solution.
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);
});
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);
});
when doesn't exist on the featureLayer. I am getting an error whenever it is about to fire.
Try to ensure the layer is loaded:
featureLayer.load().then(() => {
console.log(featureLayer.title, featureLayer.fields);
});
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);
});
}
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);
});
}
Q: did you try my suggestion of waiting for the layer to loaded first?
featureLayer.load().then(() => {
console.log(featureLayer.title, featureLayer.fields);
});
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.
Q: do you have a very simple codepen (or similar) so we can experience the issue?
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:
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: