I've been testing out Arcade expressions with the intent to create some graphs but I'm finding even simple math expressions I cannot get to work. I could just be missing something basic but I'm not starting to wonder if maybe the CSVLayer is incompatible with certain bits of Arcade, specifically some global variables like $layer.
I cut down as much as possible and I still can't get a function like Count($layer) to work even though I can access individual features like $feature.year. If I do Count([0,1]) the popup has a 2 like I'd expect. I believe I've gotten Count($layer) to work with a portal item so I think it's something specific to CSVLayer. Is there any work around or something I'm missing to get $layer to work with an in-memory CSVLayer?
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>Test</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.22/esri/themes/dark/main.css" />
<script src="https://js.arcgis.com/4.22/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/CSVLayer",
"esri/layers/Layer"
], (Map, MapView, CSVLayer, Layer) => {
const map = new Map({
basemap: "dark-gray-vector"
});
const view = new MapView({
map: map,
container: "viewDiv",
center: [-121.96, 37.87],
scale: 2000
});
//var num = Count($layer);
//var num = $feature.year;
const popupTemplate = {
content: "{expression/test}",
expressionInfos: [{
name: "test",
expression: `
var num = Count($layer);
return num;
`
}
]
};
const csv = `name|year|Longitude|latitude
aspen|2020|-121.96|37.87
birch|2018|-121.961|37.871`;
const blob = new Blob([csv], {
type: "plain/text"
});
let url = URL.createObjectURL(blob);
const csvLayer = new CSVLayer({
url: url,
renderer: {
type: "simple", // autocasts as new SimpleRenderer()
symbol: {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
size: 10,
color: "red"
}
}
});
csvLayer.popupTemplate = popupTemplate;
map.add(csvLayer);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Unfortunately, yes. $layer doesn't work for in-memory layers, like CSV, GeoJSON, etc. We document this in the description of $layer in the popup profile: https://developers.arcgis.com/arcade/guide/profiles/#popup
I admit it is a bit buried...
This is a limitation I hope we can lift soon. Will take a bit of refactoring in the Arcade engine to add support for client-side layers.
It's also a little bit clumsily worded. Since the qualifier is phrased, "In ArcGIS Online, this only applies to feature service layers." it implies it works with layers other than feature services as long as you're outside of ArcGIS Online. "This variable is only usable with feature service layers in ArcGIS Online" would have been a lot clearer. Or explicitly saying it does not work with in-memory layers would have also been good.