I have a table within my geodatabase with a list of Street IDs and Street Names. I then have a calculation rule where in my address layer I have the end user fill out the streetID and it automatically copies the Street Name out of the table and puts it in the Street Name field of the layer. This rules is then adjusted a few times in additional attribute rules to pull the street type and directional also from the table. I have this working as needed. However I wanted to add a message that pops up that when the user puts in a StreetID that doesn't exist it gives them a message instead of just doing nothing. So I added the else if statement at the end of my existing code (shown below) and now I get the error message no mater if I enter a valid ID number or Not instead of just getting it when it is not a valid ID number.
var street = FeatureSetByName($datastore, 'tStreet', ['Street_ID','St_Name'],false);
var SID = $feature.St_ID;
for(var i in street)
if(i.Street_ID == SID)
return i.St_Name
else if (i.Street_ID != SID)
return {"errorMessage": "Street ID does not exist"}
Solved! Go to Solution.
Your expression needs some brackets on it in order to flow properly.
for(var i in street) {
if(i.Street_ID == SID) {
return i.St_Name
} else {
return {"errorMessage": "Street ID does not exist"}
}
}
You could probably streamline this by filtering the streets table, instead of looping through all the streets looking for a match one-by-one. And when your condition is either/or, you can use Iif instead of a conditional block.
var street = FeatureSetByName($datastore, 'tStreet', ['Street_ID', 'St_Name'], false)
var SID = $feature['St_ID']
var matches = Filter(street, "Street_ID = @Sid") // or if the St_ID is a string, "Street_ID = '@SID'"
// check if any matches. grab name if yes, return error if no
return Iif(
Count(matches) > 0,
First(matches)['St_Name'],
{'errorMessage': 'Street ID does not exist'}
)
Your expression needs some brackets on it in order to flow properly.
for(var i in street) {
if(i.Street_ID == SID) {
return i.St_Name
} else {
return {"errorMessage": "Street ID does not exist"}
}
}
You could probably streamline this by filtering the streets table, instead of looping through all the streets looking for a match one-by-one. And when your condition is either/or, you can use Iif instead of a conditional block.
var street = FeatureSetByName($datastore, 'tStreet', ['Street_ID', 'St_Name'], false)
var SID = $feature['St_ID']
var matches = Filter(street, "Street_ID = @Sid") // or if the St_ID is a string, "Street_ID = '@SID'"
// check if any matches. grab name if yes, return error if no
return Iif(
Count(matches) > 0,
First(matches)['St_Name'],
{'errorMessage': 'Street ID does not exist'}
)
Your first code snippet won't work properly, but the second one will
Ah, you're right! I was just adding braces to the original, not even thinking about the contents of the snippet, but it'd fail in the same way the OP does. Returning outside of the loop is probably always a safer bet.
Also, don't use quotes when using @ in the sql expression. That automatically takes care of whether it has quotes or not. Using "Street_ID = '@SID'" would fail
Your code is returning the error message since the first feature in streets doesn't have the correct SID. You will only get the St_Name value back if you click on the first feature.
What you should do is return the error message after looping through all the streets. You don't need the extra "else if"
var street = FeatureSetByName($datastore, 'tStreet', ['Street_ID','St_Name'],false);
var SID = $feature.St_ID;
for (var i in street)
if (i.Street_ID == SID)
return i.St_Name
return {"errorMessage": "Street ID does not exist"}
That said, although you can do this without braces, it might be more intuitive to use braces
var street = FeatureSetByName($datastore, 'tStreet', ['Street_ID','St_Name'],false);
var SID = $feature.St_ID;
for (var i in street) {
if (i.Street_ID == SID) {
return i.St_Name
}
}
return {"errorMessage": "Street ID does not exist"}
My brain can't handle the no-braces version, I keep forgetting it actually works!
Thanks @jcarlson & @KenBuja all the codes except for the one that had the else statement, which was the other way I tried it before posting here. I'm newer to the attribute rules and using them what is the pros/cons between the way I had it written and the way jcarlson suggested utilizing the filter and count functions?
Also, I found a similar code online that someone had posted that I tweaked to get mine, they didn't have brackets and so when I copied it, I dropped the brackets too, but I had the same mind set of shouldn't this have brackets.
The larger the dataset, the faster Filter will be. For example, working with the one of the sample datasets in the Playground that had 50K records, looping through all the records took 12-14 seconds. The Filter took 0.1 seconds.
You don't need braces when using single lines after the if or for, but you always need them for multiple lines.