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.
Solved! Go to Solution.
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.
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):
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:
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";
}
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.
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.
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?
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
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.
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.
That's correct and I am sorry to make you confused because of my poor English. Thanks a lot for your help.