Select to view content in your preferred language

Allow Editing on Fields with Arcade Calculated Expressions

4097
32
08-22-2023 04:25 PM
Status: Open
Labels (2)
JoshuaFlickinger
Occasional Contributor

Idea

Allow fields to remain editable when an Arcade Expression is used to calculate them.

Reasoning

Calculated expressions are great at improving efficiency in field operations, but in advanced use cases they don't always work the way I expect them to.  Some of it may be user error on my part, but because I can't rely on my expressions, I generally end up not using them.  Allowing the field to remain editable would increase usability in the shoulder cases where my expressions fail to return expected results.

Example

I provide GIS support for a forest monitoring crew.  The crew maps trees in plots and fills out a bunch of information about each tree.  To keep track of trees over time, each tree gets a unique identifier.  I wrote an Arcade expression to create the tree ID on the fly whenever a new tree is mapped.  The expression uses a geometry intersect to determine which plot the tree is in.  Then it counts all the existing trees in that plot and adds 1 to the number of existing trees.  Finally it returns the plot and tree number in a nicely configured format. 

Works like a charm, when it works.  Unfortunately, it doesn't work when the accuracy threshold for data collection hasn't been met.  In these cases, no point exists to do the geometry intersect, but arcade still proceeds with the calculation.  It looks like it errantly picks the first plot in the list by default and returns me a blatantly wrong ID.  Would be great if I could go back in and manually input the ID in these cases.

32 Comments
LindsayRaabe_FPCWA

Interesting indeed. Maybe @DougMorgenthaler or @JeffShaner might be able to shed some light on this? Could be that you need to submit a support request through MyEsri to get it diagnosed. Could be a bug based on device type, device OS, app versions, etc. 

WetherbeeDorshow

The ability to change calculated fields is absolutely critical. For example, many data entry tasks setting the current date and time as the default is helpful. That said, there are cases when the date must be changed to log something that happened at a previous time/date. 

For fields calculated via intersection with arcade, when there are overlapping or adjacent polygons in the layer used to push values to an edit layer, often, the wrong feature is used (based on order of overlap, user's map extent when editing, etc.. ). This is why the intersect picker feature in web app builder is so useful.

For many folks, this is one reason why adoption of experience builder is lagging.

 

LindsayRaabe_FPCWA

@WetherbeeDorshow I hear you on the override option for intersected features. We have a similar process in place when an intersected feature is incorrect or simply doesn't exist so it would be good to have manual input options. We do reduce the intersection issues by adding a negative feature buffer to our source feature (which cover large areas) so it reduces the chance of intersecting a neighbouring operation. Maybe thats something that could help in your situation. See my code below and discussion here for how we do this: Solved: Help with returning value from 2 Intersecting Laye... - Esri Community

Note - the code below searches different layers based on selections in other fields, and depending on those, will reduce the search area by different amounts. The side effect is, if a feature is too small to start with (less than 500m or 2000m across depending on the reduction) then it fails to return any intersection and results in the "See Comments" value. 

var BufferedFeature1 = Buffer($feature, -250, 'meters') //Negative buffer of 250m to focus search on smaller feature types
var BufferedFeature2 = Buffer($feature, -1000, 'meters') //Negative buffer of 1000m to focus search on larger feature types
var intersectLayer1 = Intersects(FeatureSetByName($map, 'Plantations'),BufferedFeature1)
var intersectLayer2 = Intersects(FeatureSetByName($map, 'Concept Areas'),BufferedFeature1)
var intersectLayer3 = Intersects(FeatureSetByName($map, 'Harvest Plan'),BufferedFeature1)
var intersectLayer4 = Intersects(FeatureSetByName($map, 'Operation Boundaries'),BufferedFeature2)


if ($feature.EstateType == "PTN") {for(var f in intersectLayer1) {
    if(!IsEmpty(f.Plantation)) {
        return f.Plantation
    }
}
for(var f in intersectLayer2) {
    if(!IsEmpty(f.PlannedName)) {
        return f.PlannedName
    }
}}
if ($feature.EstateType == "NF") {for(var f in intersectLayer3) {
    if(!IsEmpty(f.Block_Cpt)) {
        return f.Block_Cpt + " (" + f.LOIS + ")"
    }
}}
if ($feature.EstateType == "SW") {for(var f in intersectLayer4) {
    if(!IsEmpty(f.OperationArea)) {
        return f.OperationArea
    }
}}
//Repeat the first line for all field1 and field2 values
else {return "See Comments"}

 

PamelaKing

@LindsayRaabe_FPCWA we submitted a support request for this back in July 2023 and was told it is a known limitation.  We also submitted an enhancement request (ENH-000157471: Allow Field Maps to support the use of the GetUser() arcade function in a fully disconnected offline environment). I am unable to check on its status though.  My agency allows a limited number of users to access My Esri and I am not one of them.  

LindsayRaabe_FPCWA

@PamelaKing I'll see if I can follow up on this myself. It won't show in our account but I'll reach out to support. I'd like to restore my confidence in that it is working properly instead of just nobody complaining about it yet and my Admin role making it work instead when I try it (which has happened before). 

LindsayRaabe_FPCWA

@PamelaKing I've had a chat with Esri support. Here's what they said:

In terms of the the enhancement, ENH-000157471: Allow Field Maps to support the use of the GetUser() arcade function in a fully disconnected offline environment. The current status of this is under consideration, meaning that the product team is considering adding this functionality to a future release.
 
I've tested this on my device, and it will work in an offline map when I am connected to the internet. However, when I turn wifi and mobile data on the device off the getuser() calculation does not work.
 
Are you able to test using an offline map and disconnecting the device from the internet?
 
I look forward to hearing from you.

And a followup up response after confirming it is an issue for us too :

It looks like the issue might be related to the full name function, this must be stored in the Portal, however I have tested the arcade for the username which is GetUser($layer).username and this appears to work offline.
 
Is the workaround sufficient until this functionality is implemented?

 I've since used the below logic to extract first and last names and format them correctly from our Usernames. I hope that helps!

 

//GetUser($layer).fullName
//Use the below if usernames are formatted as first.last@abc_def. 
//Uses Split to remove text "@abc_def" and then splits the remaining text using the "." 
//Returns the first and last names fortmatted using Proper case. 
Proper(concatenate([Split(Split(GetUser($layer).username,"@")[0],".")[0],Split(Split(GetUser($layer).username,"@")[0],".")[1]]," "))

Now , to go about updating all my forms with the workaround!

 

PamelaKing

@LindsayRaabe_FPCWA Thanks for the update! That is great to hear they are considering it. 

That is correct.  The code does succeed in an offline map, if the device is connected to service or wifi. 

It will not work if we are truly offline (meaning out of service with no wifi).  Our users discovered it when they were in an area with absolutely no service and we recreated it by turning off wifi and service settings then attempting to collect data in an offline map.  Same result...will not work and locks down the form.  Your only option is to discard the form and lose all the data you collected for that feature. 

Thank you for the suggested work around.  Unfortunately, our agency updated all our accounts last year and our usernames are know our PIV card numbers (2899201405120821460####_usfs) which isn't useful. 

Our work around for now is that people have to type in their names.  But I am very happy to hear they are considering updating this. 

LindsayRaabe_FPCWA

@PamelaKing I don't know how often your users change, but maybe you could consider using a table loaded into the map with the list of user ID's and their name in a separate field. The table could be updated from a source of truth (Azure?) nightly or when users are added or removed using some other process (python?) and the Arcade calculation would use getuser($layer).username to perform the lookup and return the name value. Thats all a bit beyond what I've done with python, but with the right know how, I'm sure someone could make it work. Definitely a lot of working around though compared to GetUser($layer).FullName!

Kevin_MacLeod

Just realized I created a duplicate idea, d'oh. One more +1 on this Idea. Here's another example: Let's say we have a Date_Inspected field.  We want to save users time and we put the following Calculated Expression on the field:

Now()

 

Works great, it sets the current time and date. 

What if a user's phone battery died and they got back to the office late. So the following day, they want to enter in inspections. Well, it's going to have the wrong date, it will be today, not yesterday.  

Solution:  allow users to override a Calculated Expression with their own attribute values input.

When I asked Tech Support (initially I thought this was a bug) they pointed out, this may or may not be the desired behavior.  Thus, a simple solution. An option checkbox toggle, to allow users to manually override a Calculated Expression or not to allow it, on a per-field basis in the Smart Form Designer / Field Maps Designer.

 

In general, we love Fields Maps and Field Maps Designer! 

AlixVezina