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>
Solved! Go to Solution.
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.
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.
Robert,
This makes sense, thanks so much!
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>
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
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..