saving array into the field of an array cdt

I have a rule input of type cdt array. What I want to do is to add a list of values to one of the fields by looping through another list, something like in the example below.

a!save(
ri!test.user_name,
a!forEach(
items: {1,2},
expression: "hey"
)
),

the problem is that it adds all the values to all the rows in the cdt, so it looks like this

{{ user_name: hey;hey}, {user_name: hey;hey}}

I've done this many times and never had this issue before. What am I doing wrong?

doing save(ri!test.user_name, {"hey", "hey}) returns the same output. So I don't know what's happening.

Any ideas on doing this?

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    I'm a little unclear on some assumptions you're making here - for example where does the "items: {1, 2}" list come from?

    What you have already written will save, over the entire array of ri!test, a list of "hey" text values for every "item" you iterate over.  Apparently this saves this into each member of the array.  I wouldn't have been sure without testing, but I'm not terribly surprised - Appian does certain array/set operations a bit unintuitively sometimes.

    So instead, if  we assume that your ri!test is starting with 2 members of the array and you want to save the value "hey" into both username fields, then you would so something more like

    saveInto: {
      a!forEach(
        ri!test,
        a!save(
          fv!item.user_name,
          "hey " & fv!index  /* this would make the user_name populate with "hey 1", "hey 2", etc */
        )
      )
    }

Reply
  • 0
    Certified Lead Developer

    I'm a little unclear on some assumptions you're making here - for example where does the "items: {1, 2}" list come from?

    What you have already written will save, over the entire array of ri!test, a list of "hey" text values for every "item" you iterate over.  Apparently this saves this into each member of the array.  I wouldn't have been sure without testing, but I'm not terribly surprised - Appian does certain array/set operations a bit unintuitively sometimes.

    So instead, if  we assume that your ri!test is starting with 2 members of the array and you want to save the value "hey" into both username fields, then you would so something more like

    saveInto: {
      a!forEach(
        ri!test,
        a!save(
          fv!item.user_name,
          "hey " & fv!index  /* this would make the user_name populate with "hey 1", "hey 2", etc */
        )
      )
    }

Children
  • Hey Mike, thanks for the reply. I know your solution would work in the case that ri!test already has values in it. But in my case the array is empty.

     I know I could have gone the route of looping through a list, creating a type constructor and appending to my ri!test 

    save(ri!test, foreach(items: list of values, expression: append(ri!test, type constructor with values)). However, for some weird requirement, I'm not allowed to do that, which is why I was trying to do it that other way.

  • 0
    Certified Lead Developer
    in reply to Jose H.

    if the CDT array is starting out empty, you will need to do something to instantiate its size, regardless of what else you do I think.  I mean, you could always manually construct a JSON string that would translate into roughly your CDT dictionary and then save that result back into the CDT, but I don't see that significantly deviating from the construct of looping over a constructor. 

    Note, I think you don't have to actually call the "type!" constructor itself for each item in the loop - you would need only set the property that agrees with the CDT property you want; the rest would be taken care of by the typecasting that happens automatically during the save.  If that's still not sufficient, then I'm kinda out of ideas.