IF Else Statements in Arcade Expression

21948
16
Jump to solution
08-28-2018 01:21 AM
VyNguyen3
New Contributor II

I try to create a Constraint Rule to limit the values for 2 fields which are applied 2 domains as Diameter (Double) and Material (Text). Here is my valid code and I've successfully added it. However, it always returns error when I edit feature attributes and I can't seem to understand why. 

var diameter = $feature.DIAMETER;
if (diameter == [24,30,36,48])
{$feature.MATERIAL == [CI, SP]}
else if (diameter == [18,20])
{$feature.MATERIAL == DI}

I try with other valid code as follow but it doesn't work out anyway.

var diameter = $feature.DIAMETER;
if (diameter == 24 || diameter == 30 || diameter == 36)
{$feature.MATERIAL == CI || $feature.MATERIAL == SP}
else if (diameter == 18 || diameter == 20)
{$feature.MATERIAL == DI}

Please help me correct if I was missing st and just so you know I'm not a developer so I'm really bad at this.

1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Thanks for pointing out that you already posted the domains of the fields. You are also right about the topology. There is another type of attribute rule (validation rule) that will participate in topology, but I think it hasn't been implemented yet.

Looking at the domains, there is an error in the expression regarding reading the description.  See the code below:

function IsValidMaterial(material, valid_materials) {
    var valid = False;
    for (var i = 0; i < Count(valid_materials); i++) { 
         if (material == valid_materials[i]) {
              valid = True;
          }
     }
     return valid;
}

var diameter = DomainName($feature, 'DIAMETER');
var material = $feature.MATERIAL;
var validation = False;
if ((diameter == '24"') || (diameter == '30"') || (diameter == '36"') || (diameter == '48"')) {
    var allowed_materials = ["CI", "SP"];
    return IsValidMaterial(material, allowed_materials); 
} else if  ((diameter == '18"') || (diameter == '20"')) {
    var allowed_materials = ["DI"];
    return IsValidMaterial(material, allowed_materials);
} else {
    return True;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

...  or perhaps better, just using the domain codes:

function IsValidMaterial(material, valid_materials) {
    var valid = False;
    for (var i = 0; i < Count(valid_materials); i++) { 
         if (material == valid_materials[i]) {
              valid = True;
          }
     }
     return valid;
}

var diameter = $feature.DIAMETER;
var material = $feature.MATERIAL;
var validation = False;
if ((diameter == 24) || (diameter == 30) || (diameter == 36) || (diameter == 48)) {
    var allowed_materials = ["CI", "SP"];
    return IsValidMaterial(material, allowed_materials); 
} else if  ((diameter == 18) || (diameter == 20)) {
    var allowed_materials = ["DI"];
    return IsValidMaterial(material, allowed_materials);
} else {
    return True;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

To validate what is happening you could use the expression in a pop-up and see what is returned and add some Console statements for debugging.

View solution in original post

16 Replies
DanPatterson_Retired
MVP Emeritus

if (diameter == 24 || diameter == 30 || diameter == 36) 

try

if ((diameter == 24) || (diameter == 30) || (diameter == 36))

Arcade seems to be missing an 'in' operator like python

if diameter in (24, 30, 36):

 

XanderBakker
Esri Esteemed Contributor

There are multiple things going on in your code. If you apply the suggestion made by Dan in your code there will still be things that will not work:

  • you were not assigning a value to the MATERIAL when you used a double equal sign
  • You were assigning a variable "DI" (without the quotes). Does that exist in your code. I assume it should be a string so I included the quotes
  • In the first case you were assigning a list of variables CI and SP as result. What should this be? A string including the two values like "CI, SP" or a list of string values as shown in the code below (is this accepted, can you assign a list with values in this case?)
  • You were also missing some semicolons 
var diameter = $feature.DIAMETER;
if ((diameter == 24) || (diameter == 30) || (diameter == 36) || (diameter == 48)) {
    $feature.MATERIAL = ["CI", "SP"];
} else if  ((diameter == 18) || (diameter == 20)) {
    $feature.MATERIAL = "DI";
}
VyNguyen3
New Contributor II

Hi Xander, my goal is trying to insert or update attribute data in 2 fields of a feature class which are Diameter (Double) and Material (Text), assigned respectively with 2 Domain Code descriptions as below.

 

Technically, I want to apply the value of Material corresponding to the value of Diameter that I put in the code. Besides, I test with your code and the problem remains unsolved.

.

I dont really know that it could return the list of values in Arcade or not but I read somewhere that we could identify var result () and then return result in the code. I try many expression with this idea but never succeed.

 

Lastly, I test with the simple expression as you could see in the pic below but I failed to edit as well.

0 Kudos
XanderBakker
Esri Esteemed Contributor

If my eyes don't deceive me I notice the diameter value being 20" (including the quote indicating inches). In case the field is a text field you will have to use a string comparison.Try this simple expression to see if assigning a value works:

var diameter = $feature.DIAMETER;
if (diameter == '24"'){
    $feature.MATERIAL = "CI";
} else if  (diameter == '20"'){
    $feature.MATERIAL = "DI";
}‍‍‍‍‍‍‍‍‍‍‍‍

In case the field is a field with a domain, the value should be handled differently.

XanderBakker
Esri Esteemed Contributor

Looking at the example here Add Attribute Rule—Data Management toolbox | ArcGIS Desktop I think the expression should be different. Basically the expression should be something like this:

var diameter = $feature.DIAMETER;
if (diameter == '24"'){
    return "CI";
} else if  (diameter == '20"'){
    return "DI";
}‍‍‍‍‍‍

I assume that you configured in the attribute rule that the field the rule should be applied on is MATERIAL, right?

0 Kudos
VyNguyen3
New Contributor II

This code I think is supposed for Calculation Rule because you specify what field that you're gonna return the value into. It's completely different with the Constraint Rule because there is no Field parameter in the tool dialog.

I run successfully a code similar to yours as below

0 Kudos
VyNguyen3
New Contributor II

I try again and it still returns errors as below. 

I dont know why the Constraint Rule is so complicated because I wrote a code for the Calculation Rule with the same context but for another layer (fields with domains) and had no problem. This just becomes extremely hard for a non-developer like me to define a rule.

0 Kudos
XanderBakker
Esri Esteemed Contributor

OK, now it makes more sense. I thought you were trying to implement a calculation attribute rule that assigns a material based on the diameter. However, you are implementing a constraint attribute rule that checks if a valid material is specified for the given material. A constraint attribute rule must allows return a boolean (true of false). True the constraint is met and false when an error message should be provided. I will have another look at the first expressions you provided to see how these should be changed.

0 Kudos
VyNguyen3
New Contributor II

That's correct and I am sorry to make you confused because of my poor English. Thanks a lot for your help.

0 Kudos