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
The expression for local!anyErrors in expression 2 checks if error is not null as well as its length. Though the local!errors is having 0 items yet as the function length("") returns 1. So length will return true. Similarly behavior of isnull() can be understood from below.
not(isnull({""})) returns truenot(isnull("")) returns false
length("") /*returns true*/ not(isnull({""})) /*returns true with a List of empty string*/ not(isnull("")) /*returns false with empty string*/
Given the behavior and working of isnull() and length() the value for local!anyErrors in expression 2 seems fine. To properly check and correct the behavior as per your requirement I suggest you to either replace the local!anyErrors definition with a!isNotNullOrEmpty(local!errors) or simply use local!result.anyErrors.
local!anyErrors: a!isNotNullOrEmpty(local!errors) or, local!anyErrors: local!result.anyErrors /* Either of these*/
I'm not looking for a string to be empty.... I'm looking to see if an array is empty. Why would length(someArray) be 1 if there are no items in the array? That doesn't make any sense.
You are correct in that isNullOrEmpty does return true in this case.
Given the usecase length() function is not suitable here. It seems length() in expression 2 is considered as a string rather than an array which is why 1 is returned. Below code might explain the deviation between 0 sometimes and sometimes 1. The difference is just whether its an array or not.
a!map( arrayLength: length({ "" }), /*returns 0*/ stringLength: length("") /*returns 1*/ )
So, In practice, as mentioned by almost everyone here, a!isNullOrEmpty() is best solution for cases like this.
Yep. Tested and it works. Thank you.