Null Check Validation Failing

We are having a requirement where we are getting values from an external application via a webAPI. In the web API we are casting the data into a CDT.
The value we receive from the application would be something like.
{
"person" : {"name": "Shaun","age" : 27},
"address" : {"addressLine" : "24-Wall Street","city":"London"}
}.
After this we are casting this into person and address CDT in appian and passing to the process model.


If the person and address values is empty we would be receiving the data like
{
"person" : {},
"address" :{}
}.
Now when I am casting this null Data inside CDT, this is getting casted and passed in process model like [name=null;age=null][addressLine=null;city=null].
I need to perform a null check in process model on these values which is getting failed.
Also when I am checking the length of "person" or "address" its showing as 1 instead of 0.

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    This is a very common problem. In your case, length returns 1 because there is a single item, the NULL, in there.

    In general I suggest to do all the data validation in the web API before initiating the process. If some of the fields are mandatory, then check for the individual fields.

    To check whether a variable contains "something" I created an expression over the years. It covers 23 cases of "that variable is empty".

    The rule input must be of type "any"!

    if(
      isnull(ri!value),
      true,
      a!localVariables(
        local!typeNum: runtimetypeof(ri!value),
        
        /* Strings */
        if(
          local!typeNum = 'type!{http://www.appian.com/ae/types/2009}Text',
          /* Ignore white space */
          len(trim(ri!value)) = 0,
          
        /* List of Variant */
        if(
          local!typeNum = 'type!{http://www.appian.com/ae/types/2009}Variant?list',
          all(fn!isnull, a!flatten(ri!value)),
          
        /* Lists */
        if(
          /* Try to take first item in list and cast it to a list of itself */
          /* then compare its datatype to the incoming data type */
          local!typeNum = runtimetypeof(cast(runtimetypeof({index(ri!value, 1, null)}), ri!value)),
          
          /* Flatten takes care of lists in lists in lists in ... */
          /* List has zero non-null items, length() already ignores null values*/
          length(a!flatten(ri!value)) = 0,
    
        /* DataSubsets */
        if(
          local!typeNum = 'type!{http://www.appian.com/ae/types/2009}DataSubset',
          if(
            ri!value.totalCount < 0, /* This is necessary in case fetchTotalCount=false */
            if(
              isnull(ri!value.data),
              true,
              length(ri!value.data) = 0
            ),
            ri!value.totalCount = 0
          ),
    
          /* No idea what this could be so it is considered to not be null */
          false
        ))))
      )
    )

Reply
  • 0
    Certified Lead Developer

    This is a very common problem. In your case, length returns 1 because there is a single item, the NULL, in there.

    In general I suggest to do all the data validation in the web API before initiating the process. If some of the fields are mandatory, then check for the individual fields.

    To check whether a variable contains "something" I created an expression over the years. It covers 23 cases of "that variable is empty".

    The rule input must be of type "any"!

    if(
      isnull(ri!value),
      true,
      a!localVariables(
        local!typeNum: runtimetypeof(ri!value),
        
        /* Strings */
        if(
          local!typeNum = 'type!{http://www.appian.com/ae/types/2009}Text',
          /* Ignore white space */
          len(trim(ri!value)) = 0,
          
        /* List of Variant */
        if(
          local!typeNum = 'type!{http://www.appian.com/ae/types/2009}Variant?list',
          all(fn!isnull, a!flatten(ri!value)),
          
        /* Lists */
        if(
          /* Try to take first item in list and cast it to a list of itself */
          /* then compare its datatype to the incoming data type */
          local!typeNum = runtimetypeof(cast(runtimetypeof({index(ri!value, 1, null)}), ri!value)),
          
          /* Flatten takes care of lists in lists in lists in ... */
          /* List has zero non-null items, length() already ignores null values*/
          length(a!flatten(ri!value)) = 0,
    
        /* DataSubsets */
        if(
          local!typeNum = 'type!{http://www.appian.com/ae/types/2009}DataSubset',
          if(
            ri!value.totalCount < 0, /* This is necessary in case fetchTotalCount=false */
            if(
              isnull(ri!value.data),
              true,
              length(ri!value.data) = 0
            ),
            ri!value.totalCount = 0
          ),
    
          /* No idea what this could be so it is considered to not be null */
          false
        ))))
      )
    )

Children
No Data