Calculated expressions in ArcGIS Field Maps streamline all kinds of data collection workflows from storing location as an attribute, to pulling attributes from related records or other layers in the map. In this blog post, we’ll walk through some of the most common use cases and provide sample code to get you up and running with calculated expressions in your own forms.
If you’re not familiar with Arcade, you can read the documentation or try using it in the playground. For step-by-step instructions on how to add expressions to the form in Field Maps Designer, see Add calculated expressions. Let’s jump right in and see what’s possible!
1. Fetch an attribute from an underlying polygon
Sometimes, it can be valuable to store the geographic area a feature was collected in. In the past, this could be done manually by selecting the region from a list of values or by post processing the data. Now, this can be streamlined and automatically captured in the field by using a form calculation that performs a spatial intersection of the current location and a layer of polygons representing the geographic areas.
Example: I am recording bird sightings and want to automatically store the region I’m in.
// Create a feature set using the 'Regions' layer in the map
var regions = FeatureSetByName($map, 'Regions', ['name'])
// Intersect the current location with the regions and
// get the first region
var region = First(Intersects($feature, regions))
// If the current location does intersect a feature,
// return the name of the region. Otherwise, return null
if (!IsEmpty(region)) {
return region['name']
} else {
return null
}

2. Fetch an attribute from a related record
When performing inspections, it’s often necessary to store information about the parent feature such as the address, or type of asset. These attributes can be pulled from the parent layer by querying the related records and accessing the necessary attributes.
Example: I’m inspecting hydrants and need to record the Facility ID with each inspection.
// Get the feature set for the hydrants
var hydrants = FeatureSetByRelationshipName($feature, 'wHydrant', ['facilityid'], true)
// Get the first hydrant (should only be one)
var hydrant = First(hydrants)
// If there was a hydrant, return the facilityid of it,
// Otherwise, return null
if (!IsEmpty(hydrant)) {
return hydrant['facilityid']
} else {
return null
}

3. Store a user’s name, email address, or username
When performing inspections or collecting new data, editor tracking works great for storing the username of the person who created or edited the feature, but it doesn’t store the user’s full name or email address. Having these extra attributes can make it much easier to understand the data when displayed in reports, maps, and dashboards. This can be accomplished by getting the signed in user’s info via Arcade.
Example: I’m filling out a damage inspection report and need to provide my name.
GetUser($layer).fullName
Note: At version 22.3 of Field Maps, this does not work if the device is offline.

4. Calculate the current date and time
When performing inspections, it’s often useful to set the inspection date to the current date and time. While the mobile worker can do this in the mobile app with a few taps, it can be more efficient to auto-populate this information using an Arcade expression.
Example: I’m filling out a damage inspection report and need to set the inspection date.
Now()

5. Store the geometry as an attribute
When integrating with other systems, it can be useful to store aspects of the geometry as separate attributes. This can be done by accessing the feature’s geometry via Arcade.
Example: When working with high accuracy GNSS receivers, the orthometric height is stored in the z-value of the geometry and I need to also store and display the orthometric height as an attribute value for point features collected in the field.
// Get the Z value
var geom = Geometry($feature)
if (IsEmpty(geom)) {
return null
} else {
return geom.Z
}
Sometimes, the raw x and y location are not what you need. You might need the latitude and longitude. If your map and data are using Web Mercator Projection you can write code to calculate the latitude and longitude from the x, y meter values.
Example: I need to store the latitude and longitude values to conform to some standard data collection specification.
// Create a function to convert meters to lat, long
// Source: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
function MetersToLatLon(geometry) {
if (IsEmpty(geometry)) {
return [null, null]
}
var originShift = 2.0 * PI * 6378137.0 / 2.0
var lon = (geometry.x / originShift) * 180.0
var lat = (geometry.y / originShift) * 180.0
lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0)
return [Round(lat, 6), Round(lon, 6)]
}
// Call the function and return the latitude or longitude value
MetersToLatLon(Geometry($feature))[0]

When collecting or updating the geometry of a feature, you may want to automatically calculate the length of a line or the area of a polygon as a field value. Use the AreaGeodetic() function or LengthGeodetic() function. to calculate length or area using the feature geometry instead of using the Shape_Area and Shape_Length fields. Those fields are updated after edits are submitted and your calculations may not reflect changes to the geometry.
Example: I need to store the acreage of a forest stand as an attribute and would like to round the value to 3 decimal places.
// Calculate the area using the geometry
var geom = Geometry($feature)
if (IsEmpty(geom)) {
return null
} else {
return Round(AreaGeodetic($feature, 'acres'), 3)
}
6. Calculate a value from other fields
Often, it can be useful to calculate a value based on one or more fields that the mobile user fills out.
Example: I need to calculate the score when doing a damage assessment report. Certain things (e.g., the roof, foundation, habitability.) are scored based on their damage level. I need to sum all these independent scores into a single value to use for filtering and visualization.
$feature["foundation_condition"] + $feature["roof_condition"] + $feature["habitability"]

7. Store info about a nearby feature
When installing new assets or planting trees, it’s often useful to store the nearest address.
Example: I’m planting new trees in a neighborhood and want to store the nearest address using existing parcel data.
// If feature doesn't have geometry return null
if (IsEmpty(Geometry($feature))) { return null }
// Get the parcels layer
var parcels = FeatureSetByName($map, 'Parcels')
// Buffer the current location and intersect with parcels
var bufferedLocation = Buffer($feature, 100, 'feet')
var candidateParcels = Intersects(parcels, bufferedLocation)
// Calculate the distance between the parcel and the current location
// Store the feature and distance as a dictionary and push it into an array
var featuresWithDistances = []
for (var f in candidateParcels) {
Push(featuresWithDistances,
{
'distance': Distance($feature, f, 'feet'),
'feature': f
}
)
}
// Sort the candidate parcels by distance using a custom function
function sortByDistance(a, b) {
return a['distance'] - b['distance']
}
var sorted = Sort(featuresWithDistances, sortByDistance)
// Get the closest feature
var closestFeatureWithDistance = First(sorted)
// If there was no feature, return null
if (IsEmpty(closestFeatureWithDistance)) { return null }
// Return the address
return `${closestFeatureWithDistance['feature']['ADDNUM']} ${closestFeatureWithDistance['feature']['ADDRESSNAM']}`

Summary
We’ve shown quite a few different examples here, there’s so much more that you can do with Arcade and form calculations though! If you have any questions or would like to share how you use form calculations please post in the ArcGIS Field Maps Community forum or email us at arcgisfieldmaps@esri.com.
Are these calculated expressions available in Enterprise 10.9.1? If not, is there a timeline for updating Enterprise to include this functionality?
Thanks,
Frank
The authoring UI for calculated expressions will be available in the next Enterprise release planned for this summer. They are not supported with 10.9.1.
These expressions will make our experience so much better. Can you confirm they are available for Enterprise 11?
I am toying with the first technique and even though it tests fine, the field it is supposed to populate does not populate. I got the X/Y thing to work so this is a mystery to me. One thing that is a little funny is that the $map in Globals is referring to the layer, not the name of the map, and that cannot be edited. I got the X/Y to work, but those are functions. What do you recon I’m doing wrong? var regions = FeatureSetByName($map, ‘Somaliland_And_Puntland’, [‘Region’]) // Intersect the current location with the regions and // get… Read more »
if a field already has a domain attached to it, will that affect the ability to auto-populate the fields in a created feature? The reason I ask is that my test runs (in the editor), but it does not work in practice.
As far as I know, this should work. Does the form element have “Allow Editing” unchecked? If not, the calculation will not run.
Thank you! This is so helpful. I have a question though. I’m trying auto-populate one field with lat and one with long. I used the code for this under item 5, and this gives the latitude perfectly. However, I’m having trouble figuring out how to edit the code so that it displays longitude. Does anyone know how to do this? Any help would be greatly appreciated 🙂
Hello, did you find the answer? I am having the same issues. Thanks
Ok I just changed it so that the return line only includes longitude:
return[Round(lon,6)]
Hey Aaron/Josh,
How can I recreate #7 but using a reverse geocoder to auto populate the nearest address?
Is there an expression that can be used to fetch intersecting attributes using Floor-Aware data? For instance – capturing point features and automatically capturing the intersecting facility, level, unit?
When will calculating user information work while collecting data offline?
I’m interested to know whether example #7 would work if the “nearest feature” was a tracklog being captured by Quick Capture (same user / same device) that was still actively capturing data?
Our requirement would be to obtain a project identifier from the track log and apply it to inspection records collected in Field Maps (closest track log by the same user on the same day).
Suggested Edit for Example #2: The last parameter of the FeatureSet for ‘includeGeometry’ should be set to false instead of true for the example of only needing to get the parent feature’s FaciliytID value.
The expression execution time will increase when the geometry is not returned in the FeatureSet.
Do any of these methods consume credits?
Hi, I have just been testing GetUser($layer).fullName to populate a name field, but it returns an error in the app “Failed to calculate”. When testing in FieldMaps designer it works fine, but fails in the app. Any way to get this to work?
Note many of these samples need a fix. See *** below. // Create a feature set using the ‘Regions’ layer in the map var regions = FeatureSetByName($map, ‘Regions’, [‘name’]) // Intersect the current location with the regions and // get the first region // *** right here this will fail if Intersects does not find anything. It is better to get the Intersects results then check that for IsEmpty or Count(). This is getting posted on the Esri Community boards all the time and now I know where they are getting this code. I suggest updating this code and others… Read more »