Select to view content in your preferred language

Why does Variable Order in Attribute Rule Expression Matter? Is it a bug?

1060
4
06-22-2023 11:34 AM
GregoryWhitaker
Emerging Contributor

Hello Community,

I've run into a mystery with an arcade expression that I wonder if anyone here might be able to explain. I was able to make it work fine by switching the order of variable assignment, but I can't figure out why that worked and it's bothering me.

What happened: I set variables t, d, & s with values that I use to run a simple calculation at the end of the script. Variables t & d simply grab an integer out of two different feature fields, and s grabs a feature domain code and then uses that as a key to retrieve a value from a hard-coded dictionary. The assignment order shouldn't really matter so long as I have all three values that I need at the time of calculation, which I do. And yet, it does. 

The offender is var s. When assigned before t & d, the script won't pass validation and throws a Type Error saying that it expects a string. So it thinks that $feature.GRADE is not a string when I feed it to my dictionary to retrieve the value. Unable to find a fix by doing null checks and explicit type casting, a coworker of mine jokingly told me to move var s underneath t & d. So std -> tds. For reasons, it made the error go away, the expression validated, and testing seems to indicate that it works fine.

Just wondering if anyone @ESRI might have some insight into what could be making this occur. Is this a bug?

Code snippet below. 

Thanks in advance!

 

var pipeGradeDict = {
    "A24 - 24000": 24000,
    "A25 - 25000": 25000,
    "A283 Gr B - 27000": 27000,
    "A30 - 30000": 30000,
    "B - 35000": 35000,
    "HDPE": 0,
    "HDPE - 3408": 0,
    "HDPE - 3608": 0,
    "HDPE - 4710": 0,
    "PE 3408": 0,
    "PE-C FIBERSPAR 1500": 0,
    "PE-C FIBERSPAR 750": 0,
    "PE-C FLEXPIPE 150": 0,
    "PE-C FLEXPIPE 300 / 301": 0,
    "PE-C FLEXPIPE 601": 0,
    "RI": 0,
    "UNK": 0,
    "WPB - 35000": 35000,
    "WPHY52 - 52000": 52000,
    "WPHY60 - 60000": 60000,
    "WPHY65 - 65000": 65000,
    "WPHY70 - 70000": 70000,
    "X24 - 24000": 24000,
    "X25 - 25000": 25000,
    "X30 - 30000": 30000,
    "X35 - 35000": 35000,
    "X40 - 40000": 40000,
    "X42 - 42000": 42000,
    "X42/X52 - 52000": 52000,
    "X42V - 42000": 42000,
    "X45 - 45000": 45000,
    "X46 - 46000": 46000,
    "X50 - 50000": 50000,
    "X52 - 52000": 52000,
    "X52/X60 - 60000": 60000,
    "X52M - 52000": 52000,
    "X52V - 52000": 52000,
    "X56 - 56000": 56000,
    "X60 - 60000": 60000,
    "X60C - 60000": 60000,
    "X60K - 60000": 60000,
    "X60M - 60000 THERMAL MECHANICAL ROLLED": 60000,
    "X60V - 60000": 60000,
    "X65 - 65000": 65000,
    "X65M - 65000 THERMAL MECHANICAL ROLLED": 65000,
    "X70 - 70000": 70000,
    "X70M - 70000 THERMAL MECHANICAL ROLLED": 70000,
    "XH60 - 60000": 60000,
    "XK60 - 60000": 60000,
    "XV65 - 65000": 65000,
    "Y35 - 35000": 35000,
    "Y42 - 42000": 42000,
    "Y46 - 46000": 46000,
    "Y52 - 52000": 52000,
    "Y60 - 60000": 60000,
    "Y65 - 65000": 65000,
    "Y70 - 70000": 70000
};

//Put formula in variable for use in SMYS field
//Specified minimum yield strength (SMYS) is related to the pressure inside a pipe by Barlow's formula: 
//P = 2St/D, where t is the pipe thickness in inches, and D is the outside diameter, also in inches.
//Error handling: if s & t values empty, set to 0. if d value empty, set to 1023 (0/1023 = 0)
var t = IIF(IsEmpty($feature.WALL_THICKNESS), 0, $feature.WALL_THICKNESS) //1022 = RI, 1023 = UNK
var d = IIF(IsEmpty($feature.OUTSIDE_DIAMETER), 1023, $feature.OUTSIDE_DIAMETER) //1022 = RI, 1023 = UNK
var s = IIF(IsEmpty($feature.GRADE), 0, pipeGradeDict[$feature.GRADE]) //arcade errors if this is above vars t & d??

var smysCalc = Floor(2*s*t/d, 0)

 

4 Replies
HusseinNasser2
Esri Contributor

Thanks Gregory for sharing this, anytime you find something doesn't make sense please do let us know. 

There is sure a bug here, if this is the code you are using. I expect the order matter when you have an early exist (like a check with a return) where the rest of the code won't be checked even if it has a bug. But that doesn't seem to be the case for your code

Can you share what Pro were you using? what database platform is it on (enterprise ( if yes is it oracle/sqlserver etc.. ) or filegdb/mobile etc) and maybe the schema of your class? an XML export with no data is sufficient. 

that will help us narrow down the cause.


one more thing , make sure to use haskey to check the dictionary pipeGradeDict otherwise you will get a field not found error when the value isn't part of the dictionary. 

Keep in mind the arcade validation uses the first row in the table as a candidate for validation, if table is empty, we create a dummy row with default values initialized for validation. 

the string type expected error can only happen if you are passing a number as the key where a string is expected.   

p.s. I couldn't reproduce with 3.1 , 3.0 or 2.9.10 when I move the line up t & d validation just works, yet again I created my own table with your fields there might be more to your specific Pro/dbms schema and data. 

0 Kudos
GregoryWhitaker
Emerging Contributor

Thanks for the reply, and apologies for the delayed response!

I'm currently using ArcGIS Pro 2.9.9. The data is currently sitting in a local file gdb, which is a replica of our oracle sde.

I would love to share the xml; however, even the schema alone (which is massive) does contain potentially sensitive information about my company's assets/operations, and I like being employed 😁...

I realize that isn't much to go on, but please let me know if I can answer any other questions, or if you do end up finding something related to this issue.

Appreciate the support!

0 Kudos
PeterMilenkovic
Frequent Contributor

A workaround might be to create the dictionary as a feature table in your database and filter it?

var dict = FeatureSetByName($datastore, "Dictionary")

var grade = $feature.GRADE

var filtvalue = first(filter(dict,"Code = @grade"))['Value']  

 

0 Kudos
GregoryWhitaker
Emerging Contributor

Thanks for the idea!

0 Kudos