Skip to main content
April 30, 2022
Question

isNullorEmpty

  • April 30, 2022
  • 16 replies
  • 0 views

Hi,

For the above expression rule, if I try to add a!isNullorEmpty(local!ID), then I can getting false, but I am expecting true.

Am I doing anything wrong here.

16 replies

andrewh0007
May 1, 2022

Yes, see below code and screenshot for the difference. It's subtle but technically a list containing all null indexes, even if that's a single index, isn't actually empty. This is good that this happens!

To get the behavior you want you can either reject all nulls from the list or cast to the scalar (single) integer data type. Both behaviors are demonstrated below.

a!localVariables(
  local!nullInteger: tointeger(
    null
  ),
  local!listOfNullInteger: cast(
    a!listType(1),
    local!nullInteger
  ),
  local!rejectNulls: reject(
    fn!isnull,
    local!listOfNullInteger
  ),
  local!castToScalarInteger: cast(
    typeof(1),
    local!listOfNullInteger
  ),
  {
    nullInteger: a!isNullOrEmpty(local!nullInteger),
    listOfNullInteger: a!isNullOrEmpty(local!listOfNullInteger),
    rejectNulls: a!isNullOrEmpty(local!rejectNulls),
    castToScalarInteger: a!isNullOrEmpty(local!castToScalarInteger)
  }
)
 

harshitb6843
May 1, 2022

Try using flatten before a!isnullOrEmpty(). 
Also, for future use, always create your own null checks. In that, you can loop through the input and check every item for null. This way, you can add all the conditions which should return null in the same rule. 

andrewh0007
May 1, 2022

Flatten won't help, if it were flattened it would still contain at least one null element at the end. You should also be careful with the rule you've suggested. It will work of course but you've got to make sure it's the behavior you actually want (Sometimes it is! I've made a rule like this).

A list of null elements is not empty. Imagine you query for some records and then index to a field and check if it is null or empty. If no records are found then a!isNullOrEmpty() would return true. If records are found but the field indexed to just happens to be null for all the records then a!isNullOrEmpty() should return false (and does) even if the array returned only has one item in the list.

The main issue the OP is having is the local!opinionDetails variable is returning as a list when it appears as though it will only ever have one element/index in it and so he is expecting Appian to treat it like a scalar data type even though it isn't.

davel001150
May 2, 2022

Another possibility could be the all() function.  all(fn!isNull, local!ID)

Sometimes the old looping functions still have a use.  In this case, that's pretty succinct if it works.

andrewh0007
May 2, 2022

I believe the focus shouldn't be on "fixing" a!isNullOrEmpty() when it isn't the issue. The issue is the query returns a list but is being treated like a scalar value. So focus on the actual issue. Cast the query response to a scalar data type (which was one of the solutions in my original response) and the problem (which isn't actually a problem) goes away.

Sure, what you've proposed will work. But is ignoring what the actual issue is and may lead people to believing that a!isNullOrEmpty() isn't working as it should and therefore using the fix you've proposed ubiquitously without thought as to WHY a!isNullOrEmpty() was returning false and potentially misusing it.

It's a very niche edge case though!

davel001150
May 3, 2022

I think that using "orEmpty" as in isNullOrEmpty does a great deal to imply the poster's original intent that he does want to consider the case of an empty set, and therefore IS NOT treating it as merely a scalar.

What we need to consider is the 3rd possiblity, and indeed a 4th possibility also.  There's the possibility of a null, an empty set, a set of results that are all null, and also a set of results that are all empty:

null, {}, {null, null, null}, and {{}, {}, {}}

All 4 need to be addressed appropriately as they come up.  It appears the poster's intent for the third possibility and likely the fourth as well is to treat them the same as the first and second possibilities are already treated.  Assuming this, we present possible solutions for doing this.  I leave it for the original author of this thread to share if any worked or if our assumptions about his or her intentions are mistaken.

mikes0011
Brainy
May 2, 2022

a!isNullOrEmpty() seemingly fails, specifically on the condition of "array containing one null value".  This may be the intended behavior, actually, even if it's a little bit unintuitive.  The thing you need to remember is that QueryEntity will return list-type data as a result (presuming that's what your query attempts to do), and then using "index()" to get a property from a list of dictionary will still return list-typed data (hence your result type still being "list of number").

[BTW, I still recommend using the "property()" rule instead of "index()" to get a property (as opposed to an index, since that term means the indexed position of an array), but that's just me being pedantic here.  the only impact this has is on code clarity/readability, since the two rules are aliases for each other.]

davel001150
May 2, 2022

When will they learn, Mike?  I wonder if it has something to do with the documentation of the property() function mentioning something about a "bean".

mikes0011
Brainy
May 2, 2022

I dunno.  It's always curious to me that the documentation for both is so different given that they're also described as aliases for the same back-end functionality.  Is there some training material in which index() is mentioned and property() completely omitted, i wonder?  That would explain it, but I wouldn't really know.