ArcGIS Dashboard Data Expression, "unable to execute Arcade script"

8920
27
Jump to solution
04-28-2021 09:14 AM
erica_poisson
Occasional Contributor III

Hi,

I am very new to Arcade (which you probably be able to tell by my filter expressions below).

I am attempting to create a Data Expression that can be used to power an Indicator widget in a Dashboard. I have built and tested this in the Data Expression builder within my Dashboard and when I click "test" it returns the proper result. I click done, but then see a little triangle with an ! telling me "Unable to execute Arcade script".

Why would I see this message? My Arcade script is below. Any help would be appreciated. 

var p = 'https://www.arcgis.com';
var itemID_CMpts = 'xxx';
var layerID_CMpts = 0;

var fs1 = FeatureSetByPortalItem(Portal(p), itemID_CMpts, layerID_CMpts, ['Point_Status', 'EQ_File_Number'], false);

var filterCMpts = Filter(fs1, "Point_Status ='Unstable' AND EQ_File_Number ='EQ2015-078' OR Point_Status ='Unstable' AND  EQ_File_Number = 'Eq2013-026' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2018-082' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2018-052' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2001-080X' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2003-021' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ1989-015' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2002-023' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2002-045X' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2019-110' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2020-017' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2019-091' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2018-029' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2020-033' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2019-036' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2020-052' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2019-064' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2017-040' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2020-031' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2021-003' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2011-016' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2017-026' OR Point_Status ='Unstable' AND  EQ_File_Number = 'EQ2021-020'");

var itemID_join = 'xxx';
var layerID_join = 0;

var fs2 = FeatureSetByPortalItem(Portal(p), itemID_join, layerID_join, ['Point_Status_revisit', 'EQ_File_Number'], false);

var filterJoin = Filter(fs2, "Point_Status_revisit ='Stable' AND EQ_File_Number ='EQ2015-078' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'Eq2013-026' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2018-082' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2018-052' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2001-080X' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2003-021' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ1989-015' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2002-023' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2002-045X' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2019-110' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2020-017' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2019-091' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2018-029' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2020-033' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2019-036' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2020-052' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2019-064' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2017-040' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2020-031' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2021-003' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2011-016' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2017-026' OR Point_Status_revisit ='Stable' AND  EQ_File_Number = 'EQ2021-020'");

var CntCMpts = Count(filterCMpts)
var CntJoin = Count(filterJoin)

return CntCMpts - CntJoin

 

Thank you! 

Erica
0 Kudos
27 Replies
erica_poisson
Occasional Contributor III

That worked perfectly! Thank you. 

One question I do have...what are your recommended methods for someone to learn more about Arcade? I have taken the courses available through the Esri training catalog, but felt they left a lot to be desired. I do look at the Developer Reference for Arcade, but I find this less helpful in some instances. 

Erica
0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @erica_poisson ,

The Esri Training catalog and learn paths are good ways to start. The developer help can be useful to understand each function (although sometimes it might be a bit confusing). Paul Barker has written some very good blogs on Arcade, Hussein Nasser more on Arcade in Attribute Rules and David Nyenhuis on Arcade in Dashboards: https://www.esri.com/arcgis-blog/?s=#arcade 

Basic knowledge of JavaScript might be an advantage, although Arcade is just a subset of JavaScript with some specific functions added. 

I have published some blogs/documents here in the Esri Community, but some of them are Spanish: https://community.esri.com/t5/forums/searchpage/tab/message?filter=authorId,includeTkbs&q=arcade&inc... 

What you did by reaching out to the Esri Community is a very good way of getting help when starting with Arcade or resolving complex challenges further along the road. There are many users that are willing to help others and that makes this community so great.

erica_poisson
Occasional Contributor III

@XanderBakker 

One additional question has come up. In my Dashboard, I have a map. I would like to set a Map Action so that all of my indicators are updated based on map extent. When I set this, my indicator changes to display "no data". Are map actions not compatible with elements configured via Data Expression?

Erica
0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @erica_poisson ,

That is a good question. I have seen some limitations with actions configured between widgets in the dashboard (not maps) when using data expressions. It seems that if two widgets use a different data expression, they cannot be linked (even if the resulting featureset have a common key). I can understand the logic behind this, but it is kinda limiting when it shouldn't. 

I don't think map actions will work because your featureset based on an Arcade data expression will not have the same schema as the data in the map (or perhaps does not have geometries to be filtered by extent). Use layer actions, it might work since you can specify the input and output fields that should match. However, it is most likely that it will not work as you are experiencing.

If the action should be related to those records that do not have attachments, the creation of the data expression featureset should include the individual geometries in order to filter those using the extent. This would be more work but might be possible (not sure though). 

0 Kudos
erica_poisson
Occasional Contributor III

Thank you for this information - that all makes sense and is what I suspected. I will play around with this and see if I can figure it out. 

I really appreciate all of your help and your learning suggestions. 

Erica
0 Kudos
erica_poisson
Occasional Contributor III

@XanderBakker 

Apologies for another question. I am trying to create a new data expression to populate a list with some basic information on these features that have no related records. I also want to pass through the geometry so I can then use the list to zoom to features in the map; this time I am maintaining the unique ID field "EQ File Number" which I hope will allow me to accommodate this. 

The code below is kind of a Frankenstein from the code you helped me with the other day and some other code I used in a different data expression. It creates the dictionary, but when I "Test" it just shows an empty table. I had figured I wanted to do all of this within the first for loop, but I am not really sure. If you had a suggestion, it would be appreciated. 

 

var p = 'https://www.arcgis.com';
var itemID_CMpts = 'xxx';
var layerID_CMpts = 0;
var relationshipName = "";

var fs1 = Filter(FeatureSetByPortalItem(Portal(p), itemID_CMpts, layerID_CMpts, ['Point_Status', 'EQ_File_Number', 'Inspection_Date'], true), "Point_Status ='Unstable' AND EQ_File_Number In ('EQ2015-078', 'Eq2013-026', 'EQ2018-082', 'EQ2018-052', 'EQ2001-080X', 'EQ2003-021', 'EQ1989-015', 'EQ2002-023', 'EQ2002-045X', 'EQ2019-110', 'EQ2020-017', 'EQ2019-091', 'EQ2018-029', 'EQ2020-033', 'EQ2019-036', 'EQ2020-052', 'EQ2019-064', 'EQ2017-040', 'EQ2020-031', 'EQ2021-003', 'EQ2011-016', 'EQ2017-026', 'EQ2021-020')");

var i = 0;
for (var f in fs1) {
    var fs2 = FeatureSetByRelationshipName(f, relationshipName, ['Point_Status_revisit'], false);
    var cnt = Count(fs2);
    if (cnt == 0) {
        i +=1;
        // create data schema
        var Dict = {
            'fields': [
                {'name': 'EQNum', 'type': 'esriFieldTypeString'},
                {'name': 'InspecDate', 'type': 'esriFieldTypeDate'},
                {'name': 'PtStatus', 'type': 'esriFieldTypeString'},
            ],
              'geometryType': '',
              'features':[]};
        for (var f in fs1) {
            attributes: {
                EQNum: f["EQ_File_Number"],
                InspecDate: f["Inspection_Date"],
                PtStatus: f["Point_Status"],
            },
        };
        i++
    }
    }
return FeatureSet(Text(Dict))

 

 

Erica
0 Kudos
ScottFortman1
New Contributor III

Hi there,

this solution looks promising for an expression I am working on where I am trying to use a dashboard indicator to display the result of a calculation.  I have the calculation working and followed the expression above to populate the dictionary but I am getting a blank dictionary.  Any ideas as to why it won't return 1 row with my value?

var tvwdportal = Portal('https://mapping.tvwd.org/portal')
var flush2023 = "LifeCycleStatus = 'ACTIVE' And OwnedBy = 'TVWD' And Diameter <= 12 And LastFlushDate >= date '2023-10-26'"
var main2023 = Filter(FeatureSetByPortalItem(tvwdportal,"b24772e427084f21b1f208a685d07fcc",48,['LastFlushDate','Shape__Length'],False), flush2023) ;

//split date/time with groupby function
var datesplit = GroupBy(
  main2023,
  [
    {name: 'theYear', expression: 'EXTRACT(YEAR FROM LastFlushDate)'},
    {name: 'theMonth', expression: 'EXTRACT(MONTH FROM LastFlushDate)'},
    {name: 'theDate', expression: 'EXTRACT(DAY FROM LastFlushDate)'},
  ],
  [
    {name: 'flushcount', expression: '1', statistic: 'COUNT'},
    {name: 'length', expression: 'Shape__Length', statistic: 'SUM'}
  ]
)

// calculate days remaining
var daysremaining = Round(Sum(1975006.4354237458/Average(datesplit,'length')),2)



//create dictionary to store calulated days remaining
var dict = {
    'fields': 
    [{'name':'Days_Remain', 'type': 'esriFieldTypeInteger'}],
    'geometryType': '',   
    'features': []}; 
    
//populate dictionary    
Dict.features[0] = {
            'attributes': {
                'Days_Remain': daysremaining
            }}
  
   
return FeatureSet(Text(Dict));

 

Thanks for any help! 

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @erica_poisson ,

The structure is a bit different. The schema is created once before the loop and you need to insert the results in the feature. When you need to include the geometry this is something you also need to include in the dictionary. I have not worked with returning geometries in data expression, but if I consult the syntax of the json it should be something like this:

 

 

// settings
var p = 'https://www.arcgis.com';
var itemID_CMpts = 'xxx';
var layerID_CMpts = 0;
var relationshipName = "";

// access first featureset
var fs1 = Filter(FeatureSetByPortalItem(Portal(p), itemID_CMpts, layerID_CMpts, ['Point_Status', 'EQ_File_Number', 'Inspection_Date'], true), "Point_Status ='Unstable' AND EQ_File_Number In ('EQ2015-078', 'Eq2013-026', 'EQ2018-082', 'EQ2018-052', 'EQ2001-080X', 'EQ2003-021', 'EQ1989-015', 'EQ2002-023', 'EQ2002-045X', 'EQ2019-110', 'EQ2020-017', 'EQ2019-091', 'EQ2018-029', 'EQ2020-033', 'EQ2019-036', 'EQ2020-052', 'EQ2019-064', 'EQ2017-040', 'EQ2020-031', 'EQ2021-003', 'EQ2011-016', 'EQ2017-026', 'EQ2021-020')");

// create data schema
var Dict = {
    'fields': [
        {'name': 'EQNum', 'type': 'esriFieldTypeString'},
        {'name': 'InspecDate', 'type': 'esriFieldTypeDate'},
        {'name': 'PtStatus', 'type': 'esriFieldTypeString'}],
'geometryType': 'esriGeometryPoint',
'features':[]};

// analysis and fill Dict
var i = 0;
for (var f in fs1) {
    var fs2 = FeatureSetByRelationshipName(f, relationshipName, ['Point_Status_revisit'], false);
    var cnt = Count(fs2);
    if (cnt == 0) {
        Dict.features[i] = {
            'geometry': Geometry(f),
            'attributes': {
                'EQNum': f["EQ_File_Number"],
                'InspecDate': f["Inspection_Date"],
                'PtStatus': f["Point_Status"]
            }
        };
        i++;
    }
}

return FeatureSet(Text(Dict));

 

 

 

0 Kudos
erica_poisson
Occasional Contributor III

@XanderBakker 

I have tried figuring this out by browsing through GeoNet but can't find anything relating to this issue...I added the console function right before the return statement at the end, because this is still returning an empty dictionary. When I hit "Test" and view the output from the console, I see this:

["features returned",{"fields":[{"name":"EQNum","type":"esriFieldTypeString"},{"name":"InspecDate","type":"esriFieldTypeDate"},{"name":"PtStatus","type":"esriFieldTypeString"}],"geometryType":"esriGeometryPoint","features":[{"geometry":{"x":-7997522.018099999,"y":5207172.07,"spatialReference":{"latestWkid":3857,"wkid":102100}},"attributes":{"EQNum":"EQ2013-026","InspecDate":"2020-07-29T16:00:00.000Z","PtStatus":"Unstable"}},{"geometry":{"x":-7997970.5297,"y":5214400.591300003,"spatialReference":{"latestWkid":3857,"wkid":102100}},"attributes":{"EQNum":"EQ1989-015","InspecDate":"2020-09-30T16:00:00.000Z","PtStatus":"Unstable"}},{"geometry":{"x":-7993994.632999999,"y":5212258.8379999995,"spatialReference":{"latestWkid":3857,"wkid":102100}},"attributes":{"EQNum":"EQ2020-052","InspecDate":"2020-10-19T16:00:00.000Z","PtStatus":"Unstable"}},{"geometry":{"x":-8002495.5656,"y":5219019.943500005,"spatialReference":{"latestWkid":3857,"wkid":102100}},"attributes":{"EQNum":"EQ2017-040","InspecDate":"2020-11-23T17:00:00.000Z","PtStatus":"Unstable"}},{"geometry":{"x":-7998590.2183,"y":5226627.4831000045,"spatialReference":{"latestWkid":3857,"wkid":102100}},"attributes":{"EQNum":"EQ2021-020","InspecDate":"2021-04-21T16:00:00.000Z","PtStatus":"Unstable"}}]}]

The console returns the 5 results I am looking for/know should be returned. I was unsure if this was happening because of the included geometry, so I removed that and tested again with the same result (console showing 5 features, but empty dictionary.  

Erica
0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @erica_poisson ,

In the returned json I notice that the geometry also contains the spatial reference for each feature. I am not sure if this may be causing any conflict. 

			"spatialReference": {
				"latestWkid": 3857,
				"wkid": 102100
			}

 

We can change the expression and exclude that part and see what happens. I must admit that in the past I have had situations where a correctly formed JSON is created and an empty feature set is returned. Not sure if we are running into a restriction here.

One thing we can try is this:

// settings
var p = 'https://www.arcgis.com';
var itemID_CMpts = 'xxx';
var layerID_CMpts = 0;
var relationshipName = "";

// access first featureset
var fs1 = Filter(FeatureSetByPortalItem(Portal(p), itemID_CMpts, layerID_CMpts, ['Point_Status', 'EQ_File_Number', 'Inspection_Date'], true), "Point_Status ='Unstable' AND EQ_File_Number In ('EQ2015-078', 'Eq2013-026', 'EQ2018-082', 'EQ2018-052', 'EQ2001-080X', 'EQ2003-021', 'EQ1989-015', 'EQ2002-023', 'EQ2002-045X', 'EQ2019-110', 'EQ2020-017', 'EQ2019-091', 'EQ2018-029', 'EQ2020-033', 'EQ2019-036', 'EQ2020-052', 'EQ2019-064', 'EQ2017-040', 'EQ2020-031', 'EQ2021-003', 'EQ2011-016', 'EQ2017-026', 'EQ2021-020')");

// create data schema
var Dict = {
    'fields': [
        {'name': 'EQNum', 'type': 'esriFieldTypeString'},
        {'name': 'InspecDate', 'type': 'esriFieldTypeDate'},
        {'name': 'PtStatus', 'type': 'esriFieldTypeString'}],
'geometryType': 'esriGeometryPoint',
'features':[]};

// analysis and fill Dict
var i = 0;
for (var f in fs1) {
    var fs2 = FeatureSetByRelationshipName(f, relationshipName, ['Point_Status_revisit'], false);
    var cnt = Count(fs2);
    if (cnt == 0) {
        Dict.features[i] = {
            'geometry': {
                'x': Geometry(f)["X"],
                'y': Geometry(f)["Y"]
            }, 
            'attributes': {
                'EQNum': f["EQ_File_Number"],
                'InspecDate': f["Inspection_Date"],
                'PtStatus': f["Point_Status"]
            }
        };
        i++;
    }
}

Console(Text(Dict));

return FeatureSet(Text(Dict));

 

Please share back what is returned in the console.

0 Kudos