FeatureSetByPortalItem in FieldMaps | "Object failed to load, unable to excecute task."

302
7
Jump to solution
05-08-2024 03:17 PM
i3_bmwagehoft
New Contributor II

I'm putting together an arcade expression to populate an ID attribute from a splicecase feature service "downstream" of a fiber tap cable via a Field Map form. For some reason, I can successfully calculate the ID using Arcade Editor in Field Maps Designer, but not in the mobile app. I believe I've narrowed it down to the FeatureSetByPortalItem() function. Using that function throws an error in Field Maps Troubleshooting Log (see subject line). However, when I reconfigure my map to use FeatureSetByName(), it still works in the web version, but I don't get any error in the mobile app (unfortunately, it also still doesn't calculate the ID).

Here is my code:

 

//TESTING VAULT
//var all_vaults = FeatureSetByName($map, "Auditable Vaults")
//var test_vaults = Filter(all_vaults, 'pathaccessid = 31831')
//var vault = First(test_vaults)
//Console('TEST VAULT: ' + vault)

// Get All Tap features
var const_taps = FeatureSetByName($map, "LOOKUP1",[],true)

//Get Vault Associated with Audit Record
var vaults = FeatureSetByRelationshipName($feature, "crescentlink.sde.sdm_PathAccess")
var vault = First(vaults)

//Get All Taps Intersecting Vault
var intersected_taps = Intersects(const_taps, Geometry(vault))

//Check for No Intersecting Iaps
if(Count(intersected_taps) < 1){
  Console("No Intersecting Taps. Returning NULL")
  return null
}

//Get Splicecase(s) intersecting Taps
var const_cases = FeatureSetByName($map, "LOOKUP2",['splicepointid'],true)
var intersected_cases = Intersects(const_cases, Geometry(First(intersected_taps)))

//Check for multiple intersected splicecases
if(Count(intersected_cases) > 1){
  Console("Multiple Splicecases Selected. Returning NULL")
  return null
}

//Get Splicecase VaultID
var sp_vaults = Intersects(FeatureSetByName($map, "Auditable Vaults"),Geometry(First(intersected_cases)))
var sp_vault = First(sp_vaults)

//CONSOLE OUTPUTS
Console('CONST_TAPS: ' + First(const_taps))
Console('INTERSECTED TAPS: ' + First(intersected_taps))
Console('CONST CASES: ' + First(const_cases))
Console('INTERSECTED CASES: ' + First(intersected_cases))
Console('SP VAULT: ' + sp_vault)

return Text(sp_vault.pathaccessid)+'.1'

 

  

I believe this issue has been brought up in other places, but there hasn't been any definitive reply from ESRI or the community. See here: https://community.esri.com/t5/arcgis-field-maps-questions/arcade-expression-works-in-map-viewer-but-....

Anyone run into similar issues and found a solution? Thanks in advance!

0 Kudos
1 Solution

Accepted Solutions
i3_bmwagehoft
New Contributor II

***To add insult to injury, I already posted this lengthy reply, but somehow it magically disappeared from the forums completely....come on ESRI***

~ORIGINAL REPLY POST~

I finally got this to work. Thanks @DougBrowning for the additional suggestions. I did fix an issue with an incorrect field name that was probably causing some errors, but the major issue was with the Count() function...

Here is my working code with testing/comments included:

// Get All Tap features
var const_taps = FeatureSetByName($map, "LOOKUP1",['cableid'],true)

// ESRI Communities Suggestion to fix '.' in featuresetbyrelationshipname bug
var parent_ID = $feature.pathaccessguid
var parent_ID = Upper(parent_ID)
var parent_class = FeatureSetByName($map, "Auditable Vaults",['pathaccessid','globalid'],true)
var vault = First(Filter(parent_class, 'globalid = @parent_ID'))                           
//var vault = First(Filter(parent_class, 'pathaccessid = 31831'))                            // Testing Vault

// Get All Taps Intersecting Vault
var intersected_taps = Intersects(const_taps, vault)

// TESTING
//return vault.pathaccessid + ' | ' + text(vault) + ' ||| ' + text(first(const_taps)) + ' ||| ' + Text(First(intersected_taps))    <-- FIRST STEP: THIS WORKS AND ISN'T NULL....Hmm....
//return Text(First(intersected_taps))                                                                                             <-- SECOND TEST: THIS ALSO WORKS AND ISN'T NULL!!! UGH!
//                                                                                                                                                  SELECTS INTERSECTED TAP LINES SUCCESSFULLY.

// Check for No Intersecting Taps....																								    <-- THIS WAS THE PROBLEM?!
// return Count(intersected_taps)																								      //<-- THIS RETURNS 0...WHY?!
//if(Count(intersected_taps) < 1){
//  Console("No Intersecting Taps. Returning NULL")
//  return 'NO INTERSECTING TAPS'
//}

// Get Splicecase(s) intersecting Taps
var const_cases = FeatureSetByName($map, "LOOKUP2",['splicepointid'],true)
var intersected_cases = Intersects(const_cases, First(intersected_taps))

// Check for multiple intersected splicecases																						<-- I didn't trust the Count() fuction anymore...
//if(Count(intersected_cases) > 1){
//  Console("Multiple Splicecases Selected. Returning NULL")
//  return 'MULTIPLE SPLICECASES'
//}

// Get Splicecase VaultID
var sp_vaults = Intersects(FeatureSetByName($map, "Auditable Vaults"),First(intersected_cases))
var sp_vault = First(sp_vaults)

// CONSOLE OUTPUTS
Console('CONST_TAPS: ' + First(const_taps))
Console('INTERSECTED TAPS: ' + First(intersected_taps))
Console('CONST CASES: ' + First(const_cases))
Console('INTERSECTED CASES: ' + First(intersected_cases))
Console('SP VAULT: ' + sp_vault)

return Text(sp_vault.pathaccessid)+'.1'

To be honest, I'm completely dumbfounded other than maybe there is a bug with the Count() function on Field Maps mobile?

So much for proactive error handling...

***Side Note: During my testing I noticed that Field Maps mobile is not respecting the field list array in the FeatureSetByName() functions. It returns the entire field list (['*']) regardless of what is passed to it. Seems like this would be significant hit to performance, but surprisingly the expression evaluated in a few seconds.

View solution in original post

0 Kudos
7 Replies
DougBrowning
MVP Esteemed Contributor

On this line

var const_taps = FeatureSetByName($map, "LOOKUP1",[],true)

to get all the fields you need to use ['*'].  But I would list just the fields you need instead so it will be faster.

It could also be this line

var vaults = FeatureSetByRelationshipName($feature, "crescentlink.sde.sdm_PathAccess")

It used to be a bug that this would fail if the relate has a period in it.  Not sure if that got fixed yet.  You can simulate it using Filter(FeatureSetByName())

Hope that is it.

i3_bmwagehoft
New Contributor II

Hi @DougBrowning, thanks for taking a look at this! I appreciate the suggestions.

I cleaned up the field request(s) with just the fields I need, and replaced the FeatureSetByRelationshipName() with the Filter(FeatureSetByName()) logic as suggested (shoutout to the ESRI Arcade-Expressions Github). Again, the script runs successfully within the Editor console in the web version, but fails to calculate anything in Field Maps mobile app (android). I'm using a known splicecase to evaluate the script in the Editor (Line 10). 

Successfully evaluates downstream splicecaseIDSuccessfully evaluates downstream splicecaseID

Here is the revised code:

// Get All Tap features
var const_taps = FeatureSetByName($map, "LOOKUP1",['facilityid'],true)

//Get Vault Associated with Audit Record
//var vaults = FeatureSetByRelationshipName($feature, "crescentlink.sde.sdm_PathAccess")     // Old Style, maybe bug?
var parent_ID = $feature.pathaccessguid
var parent_ID = Upper(parent_ID)
var parent_class = FeatureSetByName($map, "Auditable Vaults",['globalid'],true)
var vault = First(Filter(parent_class, 'globalid = @parent_ID'))                             // Production, based on audit record
//var vault = First(Filter(parent_class, 'pathaccessid = 31831'))                            // Testing Vault

//Get All Taps Intersecting Vault
var intersected_taps = Intersects(const_taps, Geometry(vault))

//Check for No Intersecting Taps
if(Count(intersected_taps) < 1){
  Console("No Intersecting Taps. Returning NULL")
  return null
}

//Get Splicecase(s) intersecting Taps
var const_cases = FeatureSetByName($map, "LOOKUP2",['splicepointid'],true)
var intersected_cases = Intersects(const_cases, Geometry(First(intersected_taps)))

//Check for multiple intersected splicecases
if(Count(intersected_cases) > 1){
  Console("Multiple Splicecases Selected. Returning NULL")
  return null
}

//Get Splicecase VaultID
var sp_vaults = Intersects(FeatureSetByName($map, "Auditable Vaults"),Geometry(First(intersected_cases)))
var sp_vault = First(sp_vaults)

//CONSOLE OUTPUTS
Console('CONST_TAPS: ' + First(const_taps))
Console('INTERSECTED TAPS: ' + First(intersected_taps))
Console('CONST CASES: ' + First(const_cases))
Console('INTERSECTED CASES: ' + First(intersected_cases))
Console('SP VAULT: ' + sp_vault)

return Text(sp_vault.pathaccessid)+'.1'

This code doesn't even throw any errors in the troubleshooting log on the mobile app, but fails to calculate anything in the field it's applied to in the form (already verified that this field is a TEXT datatype). It's almost like it's returning <Null> as it even lets me submit the record (which would only be possible if the script ran?).

0 Kudos
DougBrowning
MVP Esteemed Contributor

And all these layers are in the map and the name matches exactly right?  You have good checks in there to make sure each set has something in it.  Do any of these report back that it was empty?  I would add a check for vaults too.

My only guess is one of these FeatureSets is not returning something.

Also how are you zoomed?  I see this on the Intersects tool.

Feature geometries in the visualization and labeling profiles are generalized according to the view's scale resolution to improve drawing performance. Therefore, using a feature's geometry (i.e. $feature) as input to any geometry function in these contexts will return different results at each scale level. Other profiles, such as popup, provide the full resolution geometry.

i3_bmwagehoft
New Contributor II

So, I finally got this to work. Thank you again @DougBrowning for the additional suggestions. I did find one issue with an incorrect field name I was calling that probably helped clear up some errors...but the major error was with the Count() function..

Here is the working code with some of my incremental error checking/comments:

 

// Get All Tap features
var const_taps = FeatureSetByName($map, "LOOKUP1",['cableid'],true)

// ESRI Communities Suggestion to fix '.' in featuresetbyrelationshipname bug
var parent_ID = $feature.pathaccessguid
var parent_ID = Upper(parent_ID)
var parent_class = FeatureSetByName($map, "Auditable Vaults",['pathaccessid','globalid'],true)
var vault = First(Filter(parent_class, 'globalid = @parent_ID'))                           
//var vault = First(Filter(parent_class, 'pathaccessid = 31831'))                            // Testing Vault

// Get All Taps Intersecting Vault
var intersected_taps = Intersects(const_taps, vault)

// TESTING
//return vault.pathaccessid + ' | ' + text(vault) + ' ||| ' + text(first(const_taps)) + ' ||| ' + Text(First(intersected_taps))    <-- FIRST STEP: THIS WORKS AND ISN'T NULL....Hmm....
//return Text(First(intersected_taps))                                                                                             <-- SECOND TEST: THIS ALSO WORKS AND ISN'T NULL!!! UGH!
//                                                                                                                                                  SELECTS INTERSECTED TAP LINES SUCCESSFULLY.

// Check for No Intersecting Taps....																								    <-- THIS WAS THE PROBLEM?!
// return Count(intersected_taps)																								      //<-- THIS RETURNS 0...WHY?!
//if(Count(intersected_taps) < 1){
//  Console("No Intersecting Taps. Returning NULL")
//  return 'NO INTERSECTING TAPS'
//}

// Get Splicecase(s) intersecting Taps
var const_cases = FeatureSetByName($map, "LOOKUP2",['splicepointid'],true)
var intersected_cases = Intersects(const_cases, First(intersected_taps))

// Check for multiple intersected splicecases																						<-- I didn't trust the Count() fuction anymore...
//if(Count(intersected_cases) > 1){
//  Console("Multiple Splicecases Selected. Returning NULL")
//  return 'MULTIPLE SPLICECASES'
//}

// Get Splicecase VaultID
var sp_vaults = Intersects(FeatureSetByName($map, "Auditable Vaults"),First(intersected_cases))
var sp_vault = First(sp_vaults)

// CONSOLE OUTPUTS
Console('CONST_TAPS: ' + First(const_taps))
Console('INTERSECTED TAPS: ' + First(intersected_taps))
Console('CONST CASES: ' + First(const_cases))
Console('INTERSECTED CASES: ' + First(intersected_cases))
Console('SP VAULT: ' + sp_vault)

return Text(sp_vault.pathaccessid)+'.1'

 

To be honest, I'm completely dumbfounded other than this must be a bug with the Count() function in Field Maps mobile? Or maybe I just don't understand something....

The output from Intersects() is definitely a FeatureSet, from which Count should return the number of features in the set...right?

So much for proactive error handling...

***SIDE NOTE: My error checking revealed that the Field Maps mobile app is not respecting the [''] field list array in the FeatureSetByName() function. It returns all field attributes ['*'], regardless of what fields are passed to it. I'm assuming that's a serious hit to performance, but surprisingly it actually executed this expression within a few seconds***

0 Kudos
i3_bmwagehoft
New Contributor II

***To add insult to injury, I already posted this lengthy reply, but somehow it magically disappeared from the forums completely....come on ESRI***

~ORIGINAL REPLY POST~

I finally got this to work. Thanks @DougBrowning for the additional suggestions. I did fix an issue with an incorrect field name that was probably causing some errors, but the major issue was with the Count() function...

Here is my working code with testing/comments included:

// Get All Tap features
var const_taps = FeatureSetByName($map, "LOOKUP1",['cableid'],true)

// ESRI Communities Suggestion to fix '.' in featuresetbyrelationshipname bug
var parent_ID = $feature.pathaccessguid
var parent_ID = Upper(parent_ID)
var parent_class = FeatureSetByName($map, "Auditable Vaults",['pathaccessid','globalid'],true)
var vault = First(Filter(parent_class, 'globalid = @parent_ID'))                           
//var vault = First(Filter(parent_class, 'pathaccessid = 31831'))                            // Testing Vault

// Get All Taps Intersecting Vault
var intersected_taps = Intersects(const_taps, vault)

// TESTING
//return vault.pathaccessid + ' | ' + text(vault) + ' ||| ' + text(first(const_taps)) + ' ||| ' + Text(First(intersected_taps))    <-- FIRST STEP: THIS WORKS AND ISN'T NULL....Hmm....
//return Text(First(intersected_taps))                                                                                             <-- SECOND TEST: THIS ALSO WORKS AND ISN'T NULL!!! UGH!
//                                                                                                                                                  SELECTS INTERSECTED TAP LINES SUCCESSFULLY.

// Check for No Intersecting Taps....																								    <-- THIS WAS THE PROBLEM?!
// return Count(intersected_taps)																								      //<-- THIS RETURNS 0...WHY?!
//if(Count(intersected_taps) < 1){
//  Console("No Intersecting Taps. Returning NULL")
//  return 'NO INTERSECTING TAPS'
//}

// Get Splicecase(s) intersecting Taps
var const_cases = FeatureSetByName($map, "LOOKUP2",['splicepointid'],true)
var intersected_cases = Intersects(const_cases, First(intersected_taps))

// Check for multiple intersected splicecases																						<-- I didn't trust the Count() fuction anymore...
//if(Count(intersected_cases) > 1){
//  Console("Multiple Splicecases Selected. Returning NULL")
//  return 'MULTIPLE SPLICECASES'
//}

// Get Splicecase VaultID
var sp_vaults = Intersects(FeatureSetByName($map, "Auditable Vaults"),First(intersected_cases))
var sp_vault = First(sp_vaults)

// CONSOLE OUTPUTS
Console('CONST_TAPS: ' + First(const_taps))
Console('INTERSECTED TAPS: ' + First(intersected_taps))
Console('CONST CASES: ' + First(const_cases))
Console('INTERSECTED CASES: ' + First(intersected_cases))
Console('SP VAULT: ' + sp_vault)

return Text(sp_vault.pathaccessid)+'.1'

To be honest, I'm completely dumbfounded other than maybe there is a bug with the Count() function on Field Maps mobile?

So much for proactive error handling...

***Side Note: During my testing I noticed that Field Maps mobile is not respecting the field list array in the FeatureSetByName() functions. It returns the entire field list (['*']) regardless of what is passed to it. Seems like this would be significant hit to performance, but surprisingly the expression evaluated in a few seconds.

0 Kudos
DougBrowning
MVP Esteemed Contributor

Weird I use count() all the time with no issue.  I noticed I have lower case count() not Count() but I doubt that would be it.

On the FeatureSet fields thing yes that is true.  I talked to the Arcade developer personally about this.  The explanation was that assigning a FeatureSet to a var is only a pointer, it does not actually load any data in that far like most languages do.  This was for sure a surprise and we found it by trying to loop these FeatureSets and it was super slow since it was calling the data on every loop.  In addition Arcade will try to "help" you by grabbing the data needed even if you forgot.  That is why you can call a field that is not in your FeatureSet.  What is even crazier is you can set return geometry to false and still run that through intersect just fine, which I found confusing.  Again he said that it will go get it since it needs it.  I am not sure I agree with all this but it is what it is.  Note to get around this we often use code to load a FeatureSet into an array and then loop that.  

There is a big writeup on the board about all of this and our speed testing if you want to look for it.

i3_bmwagehoft
New Contributor II

For anyone coming to this thread later, I tested both Count() and count() in the calculated expression. Both return "0" for the FeatureSet in Field Maps mobile app (android, v.24.1.3 bld 1493), despite having at least one feature included within it. I'll try to submit a support ticket/bug to have ESRI investigate. The only "weirdness" I could see is with the feature layers themselves - both are Enterprise 10.9.1 Portal items being passed to AGO via URL + credentials. Maybe the output response format of the Intersects() for these isn't quite what Count() is expecting? Totally out of my depth at this point though..

@DougBrowning Thanks for the insight into the server calls that Arcade performs for these functions. I think I found that blog from jcarlson here. Definitely odd behavior from a performance standpoint for Arcade to not respect those parameters...