Hello, again.
This is a strange one.... and I'm on version 24.1.281.0
I have two expression rules... one generates some error messages (or none) and the other deals with the errors. However, in the scenario where the first expression rule generates no errors, the second one still thinks there are errors.
Expression 1: (called SH_ErrorGenerator)
a!localVariables( local!stringArray: {"a", "b"}, local!error1: "", /* value from another expression rule normally */ local!error2: "", /* value from another expression rule normally */ local!error3: {""}, /* value from another expression rule normally */ local!errors: { local!error1, local!error2, local!error3 }, local!allErrors: cast( /* make sure this is list of string not list of variant */ typeof(local!stringArray), reject(a!isNullOrEmpty, a!flatten(local!errors)) ), local!anyErrors: and(not(isnull(local!allErrors)), length(local!allErrors) > 0), { errors: local!allErrors, anyErrors: local!anyErrors } )
Expression 2:
a!localVariables( local!result: rule!SH_ErrorGenerator(), local!errors: local!result.errors, local!anyErrors: and(not(isnull(local!errors)), length(local!errors) > 0), local!anyErrors )
Here is the result I see.
result.anyErrors (calculated by SH_ErrorGenerator) is false (as it should be), but local!anyErrors (calculated by second rule) says true. And even the local variables screen says there are 0 items in the array.
Any idea what's going on here?
Thank you.
Discussion posts and replies are publicly visible
A small tweak shows the second expression sees the array as having 1 element.
a!localVariables( local!result: rule!SH_ErrorGenerator(), local!errors: local!result.errors, local!anyErrors: and(not(isnull(local!errors)), length(local!errors) > 0), { a: local!anyErrors, b: length(local!errors) } )
But, of course, you cannot actually index that item.
a!localVariables( local!result: rule!SH_ErrorGenerator(), local!errors: local!result.errors, local!anyErrors: and(not(isnull(local!errors)), length(local!errors) > 0), { a: local!anyErrors, b: length(local!errors), c: local!errors[1] } )
I’ve tried to replicate your case, and it seems that when you’re indexing the value “local!result.error”, it’s returning a list of variants. That’s why you’re getting the error you mentioned.
Actually, your scenario does not faithfully represent my code above. You are, indeed, using an array of variant by specifying {} without any qualification. I explicitly cast my data to List<string> (see first code segment above).
I don't think this will repro without using 2 expression rules. As I showed in my example, within the first expression rule, it does, rightly, know the array is empty. It's not until it is returned to the calling expression rule that the weirdness ensues.
When you use index() or dot notation, the value returned is a variant. This can produce a different result when you use the length() function.
To resolve this issue, create a map instead of a dictionary, because values stored in maps are not wrapped in a variant.
Additionally, according to the Appian documentation:When you pass an empty array to the isnull() function, it returns false. To check whether an empty list is null, use the a!isNullOrEmpty() function instead.
You are correct in that isNullOrEmpty does return true in this case.