I am working on attribute rule. It is applied on two feature classes:
1. Main_FC
2. FC_Anno
The attribute rule on Main_FC is triggered on 'Update'. The rule is:
var globalId = $feature.GLOBALID;
var attach_anno = FeatureSetByName($datastore, "FC_Anno", ["FEATUREGLOBALID", "GLOBALID"], true);
var related_feature_anno = Filter(attach_anno, "FEATUREGLOBALID = @globalId");
if (related_feature_anno != null) {
var updates = [];
for (var f in related_feature_anno) {
Push(updates, {
'globalId': f.GLOBALID,
'attributes': {
'NAME': $feature.NAME
}
});
}
return {
'edit': [{
'className': 'FC_Anno',
'updates': updates
}]
};
}
The attribute rule on FC_Anno is triggered on 'Insert & Update'. The rule is:
var fglobalId = $feature.FEATUREGLOBALID;
var main_fc = FeatureSetByName($datastore, "Main_FC", ["GLOBALID"], true);
var related_main_fc = Filter(main_fc, "GLOBALID = @fglobalId");
if (related_main_fc != null) {
var updates = [];
for (var f in related_main_fc) {
Push(updates, {
'globalId': f.GLOBALID,
'attributes': {
'NAME': $feature.NAME
}
});
}
return {
'edit': [{
'className': 'Main_FC',
'updates': updates
}]
};
}
The attribute rule works fine if I disable any one of them. When both of them are enabled together, it gives an error: The evaluation of attribute rules is cyclic or exceeds maximum cascading level.
I looked into some of community discussions & solutions suggested by @HusseinNasser2 , and I understand when one feature is edited, it triggers the rule on the other class, which again edits the first class, triggering the rule again... and so on. This causes a cyclic dependency, which leads to the cascading evaluation error. However, I am still struggling to resolve this issue.
Any help on this will greatly be appreciated. Thank you.
Solved! Go to Solution.
You need to check if each row has the same name. Try this:
var fglobalId = $feature.FEATUREGLOBALID;
var main_fc = FeatureSetByName($datastore, "Main_FC", ["GLOBALID", "NAME"], false);
var related_main_fc = Filter(main_fc, "GLOBALID = @fglobalId");
var updates = [];
for (var f in related_main_fc) {
if ($feature.NAME == f.NAME){
continue;
}
Push(updates, {
'globalId': f.GLOBALID,
'attributes': {
'NAME': $feature.NAME
}
});
}
if (Count(updates) == 0 ){
return
}
return {
'edit': [{
'className': 'Main_FC',
'updates': updates
}]
};
* Edited code, no reason to return Geometry and also needed to add NAME to the FeatureSetByName constructor
You need to add a check in each that if $feature.NAME == f.NAME, do not update it and exclude it from the return edit payload
Thank you @MikeMillerGIS for the suggestion. I tried this, it gives no error but also doesn't update the field. May be because I added return statement inside the for loop now?
var fglobalId = $feature.FEATUREGLOBALID;
var main_fc = FeatureSetByName($datastore, "Main_FC", ["GLOBALID"], true);
var related_main_fc = Filter(main_fc, "GLOBALID = @fglobalId");
if (related_main_fc != null) {
var updates = [];
for (var f in related_main_fc) {
Push(updates, {
'globalId': f.GLOBALID,
'attributes': {
'NAME': $feature.NAME
}
});
If ($feature.NAME == f.NAME ) {
return}
Else{
return {
'edit': [{
'className': 'Main_FC',
'updates': updates
}]
};
}
}
}
You need to check if each row has the same name. Try this:
var fglobalId = $feature.FEATUREGLOBALID;
var main_fc = FeatureSetByName($datastore, "Main_FC", ["GLOBALID", "NAME"], false);
var related_main_fc = Filter(main_fc, "GLOBALID = @fglobalId");
var updates = [];
for (var f in related_main_fc) {
if ($feature.NAME == f.NAME){
continue;
}
Push(updates, {
'globalId': f.GLOBALID,
'attributes': {
'NAME': $feature.NAME
}
});
}
if (Count(updates) == 0 ){
return
}
return {
'edit': [{
'className': 'Main_FC',
'updates': updates
}]
};
* Edited code, no reason to return Geometry and also needed to add NAME to the FeatureSetByName constructor
@MikeMillerGIS , unfortunately, it still doesn't work. It doesn't update now. In my original code, I have 4 fields such as NAME, NAME1, NAME2, NAME3. I have added all of them in FeatureSetByName constructor . Also, in attributes section & IF block:
if ($feature.NAME == f.NAME || $feature.NAME1 == f.NAME1 || $feature.NAME2 == f.NAME2 || $feature.NAME3 == f.NAME3){
continue;
}
I was able to resolve the update-related issue. @MikeMillerGIS ,
I think the issue was with '||'. It works when I use '&&' function in IF. I should have mentioned it before...
Thank you so much 😄 for helping me in resolving this error. I really appreciate your help.
Best Regards,
Geetesh
You still should only change the name field when it is different. So you should look at doing it this way:
// Need the expects as we are accessing attributes via variable key, this tells the code to retrieve these fields
Expects($feature, "NAME","NAME1","NAME2","NAME3");
var fglobalId = $feature.FEATUREGLOBALID;
var name_fields = ["NAME","NAME1","NAME2","NAME3"];
var main_fc = FeatureSetByName($datastore, "Main_FC", ["GLOBALID", "NAME","NAME1","NAME2","NAME3"], false);
var related_main_fc = Filter(main_fc, "GLOBALID = @fglobalId");
var updates = [];
for (var f in related_main_fc) {
var atts = {}
for (var i in name_fields){
var name_field = name_fields[i];
if ($feature[name_field] == f[name_field]){
continue;
}
atts[name_field] = $feature[name_field];
}
// IsEmpty does not work on dicts, so convert to text to see if empty
if (text(atts) == '{}'){
continue;
}
Push(updates, {
'globalId': f.GLOBALID,
'attributes': {
'NAME': $feature.NAME
}
});
}
if (Count(updates) == 0 ){
return;
}
return {
'edit': [{
'className': 'Main_FC',
'updates': updates
}]
};