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

  • 0
    Certified Associate Developer
    Instead of using an apply function how about just leveraging the set based nature of expressions? In the example below I have an arbitrary array of decimals and I'm replacing all nulls with 0's - all without an apply. You could run a similar expression on the CDT array at the end of your saveInto set and achieve what, I think, you're looking for.

    load(
    local!test: todecimal({1, 2, 3, null(), 4, null()}),

    updateArray(local!test, wherecontains(todecimal(null()), local!test), 0)
    )
  • I tried the following:
    a!save(ri!BuyerSeller.feeAmount,updateArray(ri!BuyerSeller.feeAmount,wherecontains(todecimal(null()), ri!BuyerSeller.feeAmount),0))

    and received the same result (All indexes get updated to 0). I should mention that this CDT has many more fields within it. I was only trying to update 1 field within the CDT at first just to learn how to loop through a CDT and update specific indexes. Still just trying to figure out how to update a specific index using a!save(). The reason I am using a!save() is because I want to update these null values when a user clicks the submit button.
  • 0
    Certified Associate Developer
    Is the save call with updateArray() at the end of the saveInto array?
  • Yes, within my saveInto parameter, I have the following:
    saveInto:{
    ri!isClicked,
    a!save(ri!BuyerSeller.feeAmount,updateArray(ri!BuyerSeller.feeAmount,wherecontains(todecimal(null()), ri!BuyerSeller.feeAmount),0))
    }
  • 0
    Certified Associate Developer
    Interesting - I just tried another test with dummy objects and it updates only the nulls to zero as expected (See below).

    Stupid question here but are you testing this in the interface editor or are you running a process model and clicking on the submit within a real task? Also, does the test code below work for you when you try it in a new rule?

    ------------

    load(
    local!test: {
    {Id:1, feeAmount: toDecimal(1)},
    {Id:2, feeAmount: toDecimal(2)},
    {Id:3, feeAmount: toDecimal(null())},
    {Id:4, feeAmount: toDecimal(12.31)},
    {Id:5, feeAmount: toDecimal(null())},
    {Id:6, feeAmount: toDecimal(null())}
    },
    updateArray(local!test.feeAmount, wherecontains(todecimal(null()), todecimal(local!test.feeAmount)), 0)
    )
  • Your test code worked for me. I saw the null values get updated to 0 and the non null values stayed in tact. I am trying this on a Task which is currently running within a process model. One silly question I have is how would I get "toDecimal" to be a part of my feeAmount? The feeAmount field type is a Number (Decimal) but the values look like this:
    [ID=,
    requestID=8375,
    buyerProject=1234,
    buyerTask=123,
    totalDollarAmt=23,
    totalHours=0,
    sellerProject=,
    sellerTask=,
    feeAmount=],
    [ID=,
    requestID=8375,
    buyerProject=12345,
    buyerTask=1234,
    totalDollarAmt=,
    totalHours=,
    sellerProject=,
    sellerTask=,
    feeAmount=44]

    So, if I have the following code in my a!save():
    a!save(ri!BuyerSeller,updateArray(ri!BuyerSeller.feeAmount,wherecontains(todecimal(null()), todecimal(ri!BuyerSeller.feeAmount)),0))
    I now receive an error indicating: Invalid index: "Cannot index property 'buyerProject' of type Text into type Number (Decimal)." I must be missing something big here. :)
  • 0
    Certified Associate Developer
    Ok so time for a sanity check - make sure that nothing on the output side of the task node is overwriting the feeAmount field and then check the process history to confirm what your task node is actually spitting out.

    Second your a!save statement should (I think) be:

    a!save(ri!BuyerSeller.feeAmount,updateArray(ri!BuyerSeller.feeAmount,wherecontains(todecimal(null()), ri!BuyerSeller.feeAmount),0))

    My test case wrapped the values in "toDecimal" because it was a test case and I wanted to confirm that my technique worked on decimals. In your case you have a real honest to goodness CDT with a strongly typed field present so you don't need to wrap feeAmount in toDecimal().

    Also, you shouldn't be trying to update the entire ri!BuyerSeller object, just the ri!BuyerSeller.feeAmount field.
  • Wanted to follow up about this issue: I got it to work by installing the "CDT Manipulation" plugin. forum.appian.com/.../summary

    So now on my submit button I have:
    a!save(ri!BuyerSeller, apply(rule!ReplaceNulls,ri!BuyerSeller)),

    My rule!ReplaceNulls is as follows: (input is my CDT (Any Type))
    ={

    updatecdt(
    ri!BuyerSeller,
    {
    feeAmount: if(isnull(ri!BuyerSeller.feeAmount),0,ri!BuyerSeller.feeAmount),
    totalDollarAmt: if(isnull(ri!BuyerSeller.totalDollarAmt),0,ri!BuyerSeller.totalDollarAmt),
    totalHours: if(isnull(ri!BuyerSeller.totalHours),0,ri!BuyerSeller.totalHours)
    }
    )
    }
    Thanks everyone for your ideas, help, and patience. The learning curve is slowly getting smaller. :)