I am trying to loop through a CDT and replace any null values with 0.

I am trying to loop through a CDT and replace any null values with 0.

To test this out, I added a button on my form and upon clicking the button I am executing:

a!save(ri!BuyerSeller, apply(rule!ReplaceNulls,ri!BuyerSeller)) /*ri!BuyerSeller is the CDT in which I want to loop through and replace nulls*/

My "rule!ReplaceNulls" is as follows (currently I am just trying to get 1 field to work in the CDT, but this will end up being 3 fields)
={
if(isnull(ri!BuyerSeller.feeAmount),0,ri!BuyerSeller.feeAmount)
}

I keep receiving an error about "Invalid index: Cannot index property "buyerProject" of type Text into type Number (Decimal)".
buyerProject is the first element of my CDT, but this is not one of the fields I care to parse through and check for nulls. How can I loop through a CDT and replace nulls values? Thanks

OriginalPostID-202277

OriginalPostID-202277

  Discussion posts and replies are publicly visible

  • It sounds like this would be the expected behavior of apply(). From the docs:

    apply(): Calls a rule or function for each item in a list

    This means that each field in the CDT will be an input to the rule ReplaceNulls.

    With the way that ReplaceNulls is set up, I don't think you need to use apply() here at all (just pass the entire CDT).
  • 0
    Certified Associate Developer
    Hi John,
    You were trying to save a decimal value to a CDT type. If you check the rule created for replacing nulls, it actually returns a decimal value. Here are the ways to achieve your requirement based on how many fields you need to replace in a CDT,
    1. If you need a single field value to be replaced then you can use the following expression while saving - a!save(<CDT>.<field>, rule!replaceNulls(<CDT>)).
    2. If you are not sure about the number of fields then prepare the whole CDT using 'type!<CDT>'() and configure each field value similar to this expression - if(isnull(ri!<CDT>.<field>),<replacementValue>,ri!<CDT>.<field>). For more details please check the below example for your reference to prepare CDT.
    'type!{name_space}CDT'(
    field1:if(isnull(ri!<CDT>.<field1>),<replacementValue>,ri!<CDT>.<field1>),
    field2:if(isnull(ri!<CDT>.<field2>),<replacementValue>,ri!<CDT>.<field2>)
    )
  • You can try replacing rule!ReplaceNulls contents with below code:

    if(
    isnull(ri!BuyerSeller.feeAmount),
    updatecdt(
    ri!BuyerSeller,
    {
    feeAmount: 0
    }
    ),
    ri!BuyerSeller
    )
  • Thanks for your responses. I think I am closer. I can now find the null values and replace them, however, the null values are getting replaced with a value from a different index of the CDT.

    In my button a!save() function, I now have:
    a!save(ri!BuyerSeller.feeAmount, apply(rule!ReplaceNulls,ri!BuyerSeller))

    In my "rule!ReplaceNulls", I have:
    if(isnull(ri!BuyerSeller.feeAmount),0,ri!BuyerSeller.feeAmount)

    Data as it appears before executing the button which calls this code:
    BuyerSeller[1].feeAmount: null
    BuyerSeller[2].feeAmount: 44.00

    Data as it appears after executing the button which calls the code:
    BuyerSeller[1].feeAmount: 0
    BuyerSeller[2].feeAmount: 0

    So, this code is kind of working as it is replacing the null value at index 1, however, it should not replace the 44.00 value in index 2. Can you help point me in the right direction of how I can specify indices or if I even need to?
  • Sorry, I should have mentioned, In my button a!save() function, I now have:
    a!save(ri!BuyerSeller.feeAmount, rule!ReplaceNulls(ri!BuyerSeller))

    I just need to figure out how to not replace the entire CDT if a null value is found. I only want to replace a specific index if a null value is found.
  • 0
    Certified Lead Developer
    How about this:

    Button save:
    a!save(ri!BuyerSeller.feeAmount, apply(rule!ReplaceNulls,ri!BuyerSeller.feeAmount))

    rule!ReplaceNulls:
    if(isnull(ri!feeAmount),0,ri!feeAmount)

    ...where rule!ReplaceNulls has a sinlge input of decimal type.
  • Thanks for the suggestion. Unfortunately,I receive the same result. All indices of BuyerSeller.feeAmount are getting updated to "0". I also tried this as well to specify the index:
    a!save(ri!BuyerSeller.feeAmount, apply(rule!ReplaceNulls(ri!BuyerSeller, index:_),ri!BuyerSeller)

    My rule!ReplaceNulls was changed to:

    if(isnull(ri!BuyerSeller[ri!index].feeAmount),0,ri!BuyerSeller[ri!index].feeAmount)

    However, this solution gave me an error with regards to index.
  • 0
    Certified Lead Developer
    Is ri!BuyerSeller.feeAmount a decimal? Have you tried changing the replace nulls rule to something like:

    if(ri!feeAmount>0,ri!feeAmount,0)
  • Yes it is a decimal field. However, the symptom occurs even if the filed is not a decimal. I tried your suggestion and the same symptom occurred. (still updating all occurrences of this field within the CDT).
  • 0
    Certified Lead Developer
    In which case, this must be an issue with something else on the form outside of the rule and save that you've mentioned. I've tested in isolation (see the code below) and the apply of the rule works fine. Can you set up a similar test to make sure your rules work correctly?

    (
    local!buyerSeller: {
    {feeAmount: 12.45},
    {feeAmount: 144.28},
    {feeAmount: null},
    {feeAmount: 44.91}
    },
    apply(
    rule!pb_johng_test,
    local!buyerSeller.feeAmount
    )
    )

    ....where rule!pb_johng_test is:

    (
    ri!feeAmount > 0,
    ri!feeAmount,
    0
    )