Select to view content in your preferred language

Use calculationRequired to trigger updates in another feature

134
3
Jump to solution
a week ago
Labels (1)
ErikRose
New Contributor

We have a line layer representing stormwater pipes, and a table of related records containing information about individual inspections, cleanings and maintenance.  When a worker adds a new event to the related records, I want to trigger an attribute rule to fire on the line layer to update a field with the creation date of the most recent related record.

The attribute rule that I want to trigger on the line layer looks like this:

var all_events = FeatureSetByName($datastore, "STORMWATER.stormwater_events_20250926", ['Create_Date', 'Feature_Name'], false)
var id = $feature.assetid
var events = Filter(OrderBy(all_events, 'Create_Date DESC'), "Feature_Name= @ID")
var recent = First(events)
When(recent != Null, Date(recent.Create_Date), Null)

 

From a previous thread (Attribute Rules to trigger another feature class t... - Esri Community)

@RobertKrisher writes: It is possible to force attribute rules to fire on other features when a feature is modified using the calculationRequired dictionary keyword

 

I am not sure how to implement this advice.  So far, I have tried setting an attribute rule on the table of related records to run on insert and update.  But it does not work and I am not sure how to debug it.  Any tips?

// the "asset id" field e.g. "SWGM-1002" in the related records

var id = $feature.Feature_Name

// Are variable names case sensitive here?  Is 'globalid' != 'GLOBALID'?

var out = FeatureSetByName($datastore, "pipe_maintenance", ['globalid', 'assetid'], false)

// The related records include outfall inspections (no pipe reference), so the filter can return Null
var devices = Filter(out, "assetid= @ID")
var device = When(Count(devices) > 0, First(devices), Null)

// Can I conditionally return here?
if (device != Null) {
   return {
      'calculationRequired': [{

          'className': "STORMWATER.pipe_maintenance",
          // Can I use the asset id, or only global ids?
          'globalIDs': [device] }]
   }
}

 

With this "attribute rule" in place, updates to the layer simply fail.

When a worker adds a new maintenance event, it creates a record with a creation date.  I want to update the pipe feature layer associated with the related record when this occurs, so that an attribute field in the pipe feature shows the most recent inspection date.

Thank you for your help,

Erik

0 Kudos
1 Solution

Accepted Solutions
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Hi @ErikRose,

Are you looking to have it setup so that when the related record is updated that the main feature will also update? Somethings to consider in your script.

  1. You can use either GlobalIDs or ObjectIDs as a means of updating another feature. You can use other ids to filter by but updates should only require an object id or global id.
  2. I don't think you can force a calculation but rather set it up so that when there is a change to a feature, whether it be an update or insert, you can set the rule to trigger based on one of those conditions using the $editcontext.editType and specify 'INSERT' or 'UPDATE' triggers are identified.
  3. If you want it to update another feature then I would recommend the following below.
// the "asset id" field e.g. "SWGM-1002" in the related records

var id = $feature.Feature_Name

// Are variable names case sensitive here?  Is 'globalid' != 'GLOBALID'?

var out = FeatureSetByName($datastore, "pipe_maintenance", ['globalid', 'assetid'], false)

// The related records include outfall inspections (no pipe reference), so the filter can return Null
var devices = Filter(out, "assetid= @ID")
var device = When(Count(devices) > 0, First(devices), Null)

// Can I conditionally return here?
if (typeof(device) == 'feature' {
   return {
      'result': {'attributes': Dictionary(fieldname,value) }, 'edit': [{
		  'className': "STORMWATER.pipe_maintenance",
		  "updates" : [{ 'attributes': {fieldname, fieldvalue},'globalID': device.globalid }]
	  }]
   }
}

View solution in original post

3 Replies
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Hi @ErikRose,

Are you looking to have it setup so that when the related record is updated that the main feature will also update? Somethings to consider in your script.

  1. You can use either GlobalIDs or ObjectIDs as a means of updating another feature. You can use other ids to filter by but updates should only require an object id or global id.
  2. I don't think you can force a calculation but rather set it up so that when there is a change to a feature, whether it be an update or insert, you can set the rule to trigger based on one of those conditions using the $editcontext.editType and specify 'INSERT' or 'UPDATE' triggers are identified.
  3. If you want it to update another feature then I would recommend the following below.
// the "asset id" field e.g. "SWGM-1002" in the related records

var id = $feature.Feature_Name

// Are variable names case sensitive here?  Is 'globalid' != 'GLOBALID'?

var out = FeatureSetByName($datastore, "pipe_maintenance", ['globalid', 'assetid'], false)

// The related records include outfall inspections (no pipe reference), so the filter can return Null
var devices = Filter(out, "assetid= @ID")
var device = When(Count(devices) > 0, First(devices), Null)

// Can I conditionally return here?
if (typeof(device) == 'feature' {
   return {
      'result': {'attributes': Dictionary(fieldname,value) }, 'edit': [{
		  'className': "STORMWATER.pipe_maintenance",
		  "updates" : [{ 'attributes': {fieldname, fieldvalue},'globalID': device.globalid }]
	  }]
   }
}
ErikRose
New Contributor

Thank you for pointing me in the right direction.  Here is the working version:

var id = $feature.Feature_Name
var out = FeatureSetByName($datastore, "STORMWATER.pipe_maintenance", ['globalid', 'assetid'], false)
var devices = Filter(out, "assetid= @ID")
var device = When(Count(devices) > 0, First(devices), Null)

if (typeof(device) == 'Feature') {
   return {
      'result': {'attributes': Dictionary('Event_Status', 'Success') }, 'edit': [{
         'className': 'STORMWATER.pipe_maintenance',
         'updates': [{ 'attributes': {'last_cleaned': $feature.Create_Date}, 'globalID': device.globalid }]
      }]
   }
}

 

Using the "edit" keyword to modify the target layer is a more direct approach, compared to my previous attempt trying to trigger a separate calculation rule on the target layer.

A couple clarifying questions:

In the above example, I pass a dictionary into the 'result' key that sets the 'Event_Status' field to 'Success'.  In this case, I do not need a result value.  Is the 'result' key word required?  Can I pass it an empty dictionary without issue?

When the script for an attribute rule is not working on an Enterprise branch service, it can be time consuming to explore fixes, having to disable and re-enable the service, etc.  Within the scripting window, I can use the Console() function to inspect example output.  Is there a way I can log these outputs to a file to inspect later?  I ended up packing any information I needed into the 'errorMessage' keyword, which I can inspect on a failure.  Is this the recommended way to debug an attribute rule?

0 Kudos
RobertKrisher
Esri Regular Contributor

When possible, doing your initial development/testing in a local mobile geodatabase can speed up the process greatly. Another trick is to write as much of the code as possible using a popup expression (since it shares many of the same profiles/functions as attribute rules), this saves you having to bounce services, gives you access to console, and lets you test it out on different features.