Select to view content in your preferred language

Error "The evaluation of attribute rules is cyclic or exceeds maximum cascading level"

347
6
Jump to solution
05-13-2025 02:52 AM
GeeteshSingh07
Frequent Contributor

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.

--
Best Regards,
Geetesh
geetesh486@gmail.com
0 Kudos
1 Solution

Accepted Solutions
MikeMillerGIS
Esri Frequent Contributor

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 

View solution in original post

6 Replies
MikeMillerGIS
Esri Frequent Contributor

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

0 Kudos
GeeteshSingh07
Frequent Contributor

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
        }]
    };
}

}   

}

--
Best Regards,
Geetesh
geetesh486@gmail.com
0 Kudos
MikeMillerGIS
Esri Frequent Contributor

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 

GeeteshSingh07
Frequent Contributor

@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;
    }

 

--
Best Regards,
Geetesh
geetesh486@gmail.com
0 Kudos
GeeteshSingh07
Frequent Contributor

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

 

--
Best Regards,
Geetesh
geetesh486@gmail.com
0 Kudos
MikeMillerGIS
Esri Frequent Contributor

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
    }]
};

 

0 Kudos