isNullorEmpty

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.

  Discussion posts and replies are publicly visible

  • 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)
      }
    )
     

  • 0
    Certified Lead Developer
    in reply to ajhick

    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. 

  • 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.

  • 0
    Certified Lead Developer

    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.

  • 0
    Certified Lead Developer

    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.]

  • 0
    Certified Lead Developer
    in reply to Mike Schmitt

    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".

  • 0
    Certified Lead Developer
    in reply to Dave Lewis

    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.

  • Obviously I can't speak for Appian but from my perspective it *should* work this way, as in a!isNullOrEmpty() is not failing. A list of null isn't empty, null is a perfectly reasonable "value" to return. There's a massive difference between null being return (eg. Nothing was found) and a list of null being returned (Eg. Things were found and the value(s) were null).

    I fully agree that queries returning a single record returning as lists can be problematic, but that's not an issue with a!isNullOrEmpty(). I also haven't fully thought about why queries would return lists, there may be a good reason...or maybe not! Maybe if the entity being queried is a primary key or has a unique constraint and the "=" operator is used then Appian could be smart enough to not return it as a list.

    Not sure, but either way, a!isNullOrEmpty() is working as far as I expect it should. This is not a blind defence of bad functionality either, I have use cases where I want a!isNullOrEmpty() to return false when given a list of null, even when that list contains only one element.

    And if the intended behaviour is to check if every element in an array is null then we have the tools at our disposal to do so. Best of both worlds!

  • 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!

  • 0
    Certified Lead Developer
    in reply to ajhick

    Right.  I do think that there's a massive difference between an empty shopping bag, and a shopping bag containing an empty shopping bag (especially if the shopping bag in your shopping bag has a price tag on it).  Likewise, a massive difference between a lunchbox with nothing in it and a lunchbox with an empty thermos in it.  Especially on ebay.

    It absolutely should make a distinction between returning no results and returning some results that happen to be empty or null.  Nothing is interesting.  A set of 4 nulls is interesting in a completely different way.

    Mike and I are just striking up an old conversation about how index() should be for indeces and property() should be for properties.  a!update() is amazing, but it's a bad sign that the keyword for the property you want to alter is "index:".  Amiright?