Update failure via attribute rules with arcade

2385
12
Jump to solution
04-01-2021 10:10 AM
ZhiyongHong
New Contributor II

Our team is trying to use Arcade to do some data updates without success and I have reduced the update to be the simplest possible. Basically, this is to copy the data to 'notes' when this field changed. I am on pro 2.7 and I am using file geodatabase. Could anyone see what is wrong with this arcade expression or do I need to configure something for update via arcade? Thanks in advance for any helps! Following are the screenshots of the error we received and the arcade expression.

ZhiyongHong_0-1617296891713.pngZhiyongHong_1-1617296999979.png

 

 

0 Kudos
1 Solution

Accepted Solutions
SarahHartholt
Occasional Contributor III

yes, as soon as I change the name in the name field, it is updated in the notes field as well. 

If you want to pass a value from another feature's attribute table that can be accomplished but you need to know which feature is passing the attribute and which feature is receiving the attribute. My use case for the following code is to buffer each feature in my centreline feature class by 10m, when a watermain feature falls within 10m of a centreline, my expression grabs the coordinated_ID value from the centreline feature and passes it to the coordinated_ID field in the watermain attribute table. When multiple centreline features intersect with the watermain feature, it grabs the coordinated_ID from the longest centreline.  when features don't intersect, the coordinated_ID field is populated with null.

 

 

 

//On Insert or Update populate Coordinate ID 
var fsRoads = FeatureSetByName($datastore, "Centreline_Assets",["Coordinated_ID"], True);
var watermain = $feature;
var watermainbuf = Buffer(watermain, 10, 'meter');
var roads = Intersects(fsRoads, watermainbuf);
var cnt = Count(roads);

// check different situations
if (cnt == 0) {
    // there are no roads found
    return null;
} else if (cnt == 1) {
    // there is a one road, return the Coordinate_ID
    return First(roads)["Coordinated_ID"];
} else {
    // there are multiple roads found, find the longest segment
    var maxsegmentlength = 0;
    var CoordID = null;
    for (var road in roads) {
        var segment = Intersection(road, watermainbuf);
        var segmentlength = Length(segment, 'meter');
        if (segmentlength > maxsegmentlength) {
            CoordID = road["Coordinated_ID"];
            maxsegmentlength = segmentlength;
        }
    }
    return CoordID;
}

 

 

 

View solution in original post

12 Replies
SarahHartholt
Occasional Contributor III

if you're using attribute rules, a simple arcade query like this works:

 

var name = $feature.Name;
return name

 

SarahHartholt_0-1617303321489.png

SarahHartholt_1-1617303350822.png

right click your feature layer -> Design -> attribute rules

set the expression:

var name = $feature.Name;
return name

and make sure to set the trigger as update 

ZhiyongHong
New Contributor II

Thanks, @SarahHartholt . This will work if just returning some data. The problem for us is that we need to update some data from the attribute rule. 

0 Kudos
SarahHartholt
Occasional Contributor III

I don't think I'm understanding what you are trying to accomplish then. Your original post makes it seem like you want to pass a value from one attribute to another. i.e. when someone updates the comments field, it also updates the notes filed with the same text. Can you add some more context?

ZhiyongHong
New Contributor II

Oops. I did not see that your rule is applied to "notes" and the value you are returning is the name. So is that right you script will update the notes field from the name as long as anything in this feature is changed? What we are trying to accomplish is to use the "Edit"/"updates"  payload from arcade to run the update. Our real use case is more complicated than this. We will use the association to update the attributes in different features via querying the association of the features. We have confirmed that we could get all the data well but the update fail. Do you have a simple general example that I could check that use the approach like this for update? 

ZhiyongHong_0-1617304549652.png

 

 

0 Kudos
SarahHartholt
Occasional Contributor III

yes, as soon as I change the name in the name field, it is updated in the notes field as well. 

If you want to pass a value from another feature's attribute table that can be accomplished but you need to know which feature is passing the attribute and which feature is receiving the attribute. My use case for the following code is to buffer each feature in my centreline feature class by 10m, when a watermain feature falls within 10m of a centreline, my expression grabs the coordinated_ID value from the centreline feature and passes it to the coordinated_ID field in the watermain attribute table. When multiple centreline features intersect with the watermain feature, it grabs the coordinated_ID from the longest centreline.  when features don't intersect, the coordinated_ID field is populated with null.

 

 

 

//On Insert or Update populate Coordinate ID 
var fsRoads = FeatureSetByName($datastore, "Centreline_Assets",["Coordinated_ID"], True);
var watermain = $feature;
var watermainbuf = Buffer(watermain, 10, 'meter');
var roads = Intersects(fsRoads, watermainbuf);
var cnt = Count(roads);

// check different situations
if (cnt == 0) {
    // there are no roads found
    return null;
} else if (cnt == 1) {
    // there is a one road, return the Coordinate_ID
    return First(roads)["Coordinated_ID"];
} else {
    // there are multiple roads found, find the longest segment
    var maxsegmentlength = 0;
    var CoordID = null;
    for (var road in roads) {
        var segment = Intersection(road, watermainbuf);
        var segmentlength = Length(segment, 'meter');
        if (segmentlength > maxsegmentlength) {
            CoordID = road["Coordinated_ID"];
            maxsegmentlength = segmentlength;
        }
    }
    return CoordID;
}

 

 

 

ZhiyongHong
New Contributor II

Thanks so much, @SarahHartholt. I have tried your first example and it works great for its use case and it also helps me clarify some concepts! For your second example, I am wondering how do you define the attribute rules since the trigger and receiver are different. I guess you will need to define the rule for "watermain" on "coordinated_ID" to receive the change. How do you define the trigger from Centreline_Assets? A screenshot of your rule definition like in your first example should help a lot! 

0 Kudos
SarahHartholt
Occasional Contributor III

It's a calculate rule that is set on my watermain feature class. The trigger is Update just like the first example. When I make a change to a feature in the watermain feature class (the receiver), the arcade expression executes.

I think the key for you is this line which calls the Centreline_Assets layer in my map. (the giver)

 

 

var fsRoads = FeatureSetByName($datastore, "Centreline_Assets",["Coordinated_ID"], True);

 

 

it is telling the expression to look in the map document ($datastore) for a layer called Centreline_Assets, and to grab the Coordinated_ID field in its attribute table. 

SarahHartholt_0-1617307012547.png

 

ZhiyongHong
New Contributor II

I think I kind of get it. So this example defines the rule in watermain. If I get it right, it will require a change in watermain to trigger copying the value of "Coordinated_ID" from Centreline_Assets to watermain. Could you think of a way to this scenery: Triggering the data copy from Centreline_Assets to watermain when it detects changes in Centreline_Assets?

0 Kudos
SarahHartholt
Occasional Contributor III

A change to any attribute in the watermain layer triggers the arcade expression to execute. I'm not sure if that also includes changes to the geometry/shape of the feature though.

I'm not sure if that is possible. Your trigger would need to be on the Centreline_Assets layer but the field to update would be on the watermain layer which is not something you can select from the Field dropdown

SarahHartholt_0-1617310412941.png