Hello. I'm attempting to pass a value from a parent feature to a related table using an Attribute Rule. The idea being that when a new related record is created it automatically populates this field based on its corresponding parent value. This seems like it should be easy to do but the arcade expression is proving challenging for my beginner level of arcade experience. The fields are both called "GPMDesign" and are both "Long" field types. I'm running ArcGIS Pro 2.7.1 and Enterprise 10.8.1. Thank you!
// calculation attribute rule on child // field: if you want to get only one field from the parent, then chose // that field. if you want to get multiple fields, leave empty // triggers: Insert(, update) // load the related parent features using one of these methods // if you have a relationship class between parent and child: var parent_fs = FeatureSetByRelationshipName($feature, "RelationshipName") // if not var parent_fs = FeatureSetByName($datastore, "NameOfParentFC") var key = $feature.ForeignKeyField parent_fs = Filter(parent_fs, "PrimaryKeyField = @key") // return nothing if no parent feature was found var parent = First(parent_fs) if(parent == null) { return } // if you want to return only one field: return parent.Field // if you want to return multiple fields: var att = { "Field1": parent.Field1, "Field2": parent.Field2 } return {"result": {"attributes": att}}
Thanks....yes, I tried both with FeaturesetByName and FeaturesetByRelationshipName, but get the same results either way.
I'll add some console messages and try to figure this out.
Thanks for your help!
It looks as if the rule doesn't find the parent feature and aborts in line 6. You could test that theory by returning a default value if that happens.
Also, you're getting the related features in line 1 and then filter these features in lines 2&3. I used FeaturesetByName in my example and had to use the filter to get the related features. You use FeaturesetByRelationshipName, so the parent_fs already contains only the related features, the filter doesn't do anything.
var parent_fs = FeatureSetByRelationshipName($feature, "SAN_Manhole_To_SAN_Manhole_Inspection"); var manhole = First(parent_fs); if (manhole == null) {return {"result": {"attributes": {"LOCATIONDESCRIPTION": "No parent feature found!"}}}}; var atts = { "LOCATIONDESCRIPTION": manhole.LOCATIONDESCRIPTION, "SETTLEMENTAREA": manhole.SETTLEMENTAREA, "LOCALMUNICIPALITY": manhole.LOCALMUNICIPALITY, "DEPOTAREA": manhole.DEPOTAREA }; return {"result": {"attributes": atts}};
Hi @JohannesLindner . So I'm using the code below which kind of works for updating multiple fields in the child object based on the matching field in the parent, but it only works when I update the child, not when the child is first created. (I do have both the update and insert triggers checked).
Is there something I am missing in order to get it to work when the records is first created??
var parent_fs = FeatureSetByRelationshipName($feature, "SAN_Manhole_To_SAN_Manhole_Inspection"); var key = $feature.FACILITYID; parent_fs = Filter(parent_fs, "FACILITYID = @key"); var manhole = First(parent_fs); if (manhole == null) {return}; // get the manhole feature //var manholes = FeaturesetByName($datastore, 'SAN_Manhole', ['LOCATIONDESCRIPTION', 'SETTLEMENTAREA', 'LOCALMUNICIPALITY', 'DEPOTAREA'], false); //var facility_id = $feature.FACILITYID; //var manhole = First(Filter(manholes, 'FACILITYID = @facility_id')); //if (manhole == null) {return}; var atts = { "LOCATIONDESCRIPTION": manhole.LOCATIONDESCRIPTION, "SETTLEMENTAREA": manhole.SETTLEMENTAREA, "LOCALMUNICIPALITY": manhole.LOCALMUNICIPALITY, "DEPOTAREA": manhole.DEPOTAREA }; return {"result": {"attributes": atts}};
Amazing! Thank you.
I was starting to come to this conclusion yesterday but I could not quite figure out how to "word" the filter and just kept getting errors. Works great now and I have duplicated it to provide the totals for all of our different statuses into the parent field.
var child_fs = FeatureSetByRelationshipName($feature, "ApplicationSite_TurfArea", ['Area', 'Status']) var filterd_child_fs = Filter(child_fs, "Status = 2") if(filterd_child_fs == null) { return } return Sum(filterd_child_fs, "Area")
With the help of this blog https://github.com/Esri/arcade-expressions/blob/master/attribute_rule_calculation/UpdateParentFeature.md I was also able to add an event to the child fields to trigger the recalculation if only they were edited and not the parent field.
// This rule will update an attribute in the parent feature // Store the parent feature global from the key field in the relationship var parent_id = $feature.GUIDApplicationSite; if (IsEmpty(parent_id)) return parent_id; // force to upper as the sql is case sensitive parent_id = Upper(parent_id); // Using the GDB name, get the parent classes records and Global ID field var parent_class = FeatureSetByName($datastore, "ApplicationSite", ["globalid", 'laststatus'], false); // Filter the parent class for only related features var parent_records = Filter(parent_class, "globalid = @parent_id"); var updates = []; var i = 0; var new_value = 0; if (IsEmpty($feature.Status) == False) { new_value = $feature.Status } // Loop through each feature, create a dict of the Global ID and the new value date for (var row in parent_records) { // If the parent row is null or has a different value, updated it if (IsEmpty(row['laststatus']) || row['laststatus'] != new_value) { updates[i++] = { 'globalid': parent_id, 'attributes': {"laststatus": new_value} }; } } // Return the original value in the result parameter, as to not lost the entered value // Using the edit parameter, return the class and list of updates return { 'result': parent_id, 'edit': [ {'className': 'ApplicationSite', 'updates': updates } ] };
I probably could have simplified it better since I am not looking through multiple fields to get the status but it all seems to work very nicely now.
I am a little curious what will happen to all this when I transfer it to AGOL so it can be used in field maps LOL but I guess I will find out soon enough.
Thank you, again.
Sum() takes a Featureset and a field als arguments.
I included a Filter() to search for the value in the status field.
var child_fs = FeatureSetByRelationshipName($feature, "ApplicationSite_TurfArea", ['Area', 'Status']) var filterd_child_fs = Filter(child_fs, "Status = 'post inspection'") return Sum(filterd_child_fs, "Area")
Fingers crossed that someone may still be following this thread.
I am trying to alter this code to 1) go from children to parent and 2) with a sum on the child field instead of the first record being transferred. I have so far only managed to successfully complete 1. I have tried various ways of using Sum() in different locations and finally came to a way where it didn't give me an error but it still only give me the first record not the sum.
I am totally new to python so I am just using trial and error here and apologize if the answer is looking right back at me but any help would be appreciated.
/// calculation attribute rule on parent // field: if you want to get only one field from the child, then chose // that field. if you want to get multiple fields, leave empty // triggers: Insert(, update) // load the related child features using one of these methods // if you have a relationship class between parent and child: var child_fs = FeatureSetByRelationshipName($feature, "ApplicationSite_TurfArea", ['Area']) // return nothing if no child feature was found var child = sum($feature,child_fs) if(child == null) { return } // if you want to return only one field: return child return {"result": {"attributes": att}}
Additionally this is going to get more complicated as I want to eventually create a sum from the Area based on the input for another field. i.e. some all child areas that have "post inspection" in the Status field. But I found that if I work out one piece of a code at a time I can try to piece them together.
var parent_fs = FeatureSetByRelationshipName($feature, "Matstallen_Rate", ['Namn'])
Thanks Johannes, but sadly it doesn't work.
This error occurs. Any suggestions to what might be the issue?
I'm new to Arcade, and I've been trying to find the solution for days now, but I'm stuck.
Your problem is in the last line: You try to return the whole parent feature. Even if you only load one field (Namn), the feature still holds other information, such as geometry. You have to specify what field you want to return:
return parent.Namn
Hi!
I'm trying this and can't make it work somehow.
My feature class, relationship class and table are stored in an sde database. I have a relationship class between parent and child. My script looks like this. It validates but when I create a new feature the field in which the attriute rule is applied won't update.
// calculation attribute rule on child// field: if you want to get only one field from the parent, then chose// that field. if you want to get multiple fields, leave empty// triggers: Insert(, update)
// load the related parent features using one of these methods// if you have a relationship class between parent and child:var parent_fs = FeatureSetByRelationshipName($feature, "Matstallen_Rate", ['Namn'])
// return nothing if no parent feature was foundvar parent = First(parent_fs)if (parent == null) { return }
// if you want to return only one field:return parent
Super thankful for your help
Thanks Johannes! This helped me develop what I was looking for. Simple and straightforward. Much appreciated.
The rules are fairly complicated, but I can find them by Right Clicking on Address Points in the table of contents, selecting Design and then Attribute Rules. In the solution, the work flow has the user drop an Address Point on a street centerline and through a relationship class a Site Address Point is created.
Thanks Joe. I think I found what you were referring to in one of the web map's pop up configurations. Neither the tables or feature layers had actual Attribute Rules on them that I could see. It still seems way more complicated than it should though. I'll keep tinkering with the FeatureSet functions.
Take a look at the ESRI Address Data Management Solution; it has similar rules written between address points and related site address points. There is an aprx you can download that has sample data and the rules are applied there.
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.