Let me share with you the results of this code snippet
a!map( length: length(local!taller.resultado.contractSetting.annuitySettings.paymentMethods), pm: local!taller.resultado.contractSetting.annuitySettings.paymentMethods, isnull: a!isNullOrEmpty(local!taller.resultado.contractSetting.annuitySettings.paymentMethods) )
I'm wondering why length of a null array is equal to 1.I appreciate any explanation to this.
Regards
Discussion posts and replies are publicly visible
Impossible to say without knowing exactly what this data structure looks like.
It looks like this:
Here you have direct output from the service which this data come from, in json format
"annuitySettings":{"paymentMethodTypeCode":"","paymentMethodTypeDesc":"","paymentMethods":[]},
The problem here is the edge cases around empty lists and variants. The following snippet replicates that.
length(cast(type!Variant, {}))
Try to cast that empty list of dictionaries into a list of Maps. Not great, but works for me.
length(cast(a!listType(type!Map), local!data.annuitySettings.paymentMethods))
Thank you Stefan, it works.
I had solved the error with this
and( length(local!taller.resultado.contractSetting.annuitySettings.paymentMethods) = 1, a!isNotNullOrEmpty(local!taller.resultado.contractSetting.annuitySettings.paymentMethods) ),
Both solution are quite ugly
I think that Appian engineers should work on this, it is not coherent that length funntion returns 1 on an empty array
Or you might utilize Stefan's rule 'isVoid' checking for empty structures (all sorts of). ri!value is of type 'Any Type'
if( a!isNullOrEmpty(ri!value), true, a!localVariables( local!typeNum: a!refreshVariable( value: runtimetypeof(ri!value), refreshAlways: true ), /* 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(a!isNullOrEmpty(_), 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, /* Map */ if( local!typeNum = 'type!{http://www.appian.com/ae/types/2009}Map', /* Has no keys at all or all values are null */ or( length(a!keys(ri!value)) = 0, all(a!isNullOrEmpty(_), index(ri!value, a!keys(ri!value), null)) ), /* DataSubsets or Maps returned by queryRecordType */ if( or( local!typeNum = 'type!{http://www.appian.com/ae/types/2009}DataSubset', and( local!typeNum = 'type!{http://www.appian.com/ae/types/2009}Map', contains(a!keys(ri!value), "data"), ) ), a!isNullOrEmpty(ri!value.data), /* No idea what this could be so it is considered to not be null */ false ) ) ) ) ) ) )