How to delete rows from arrays of arrays (Nested CDTs)?

Certified Associate Developer

Hello All, I have a requirement where we need to delete rows based on array's of arrays(nested arrays) when i tried to implement the logic and try to delete the rows i'm getting the below error message as shown.

Can you please let me know what could be the best solution or approach  to achieve this requirement.

CDT structure:

Delete code:

Error screenshot:

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer

    The error message tries to tell you that CTRIS_Part1_Sponsor_ThirdPartyOrg does not have a field called thirdPartyOrgDetails.

  • 0
    Certified Associate Developer
    in reply to Stefan Helzle

    Please find the below screenshot for better understanding on how we are using arrays of arrays.

    {
    'type!{urn:com:appian:types:CTRIS}CTRIS_Part1_SponsorDetails'(
    'ctrisId': 1473,
    'sponsorName': "GSK R&D Ltd",
    'organizationType': "Commercial",
    'thirdPartyOrgDetails': {
    'type!{urn:com:appian:types:CTRIS}CTRIS_Part1_Sponsor_ThirdPartyOrg'(
    'ctrisId': 1473,
    'orgId': "Test Organisation ID",
    'orgName': "Test Name of organisation",
    'duties': "Statistical Analysis,Q/A auditing",
    'tpAddress': 'type!{urn:com:appian:types:CTRIS}CTRIS_AddressDetails'(
    'ctrisId': 1473,
    'context': "Third Party Organisations associated with the trial",
    'addressLine1': "Address: Street name",
    'country': "USA",
    'phone': "1234567",
    'email': "test@gsk.com"
    ),
    ),
    'type!{urn:com:appian:types:CTRIS}CTRIS_Part1_Sponsor_ThirdPartyOrg'(
    'ctrisId': 1473,
    'orgId': "Test Organisation ID 2",
    'orgName': "Test Name of organisation 2",
    'duties': "Safety reporting,E-Data capture",
    'tpAddress': 'type!{urn:com:appian:types:CTRIS}CTRIS_AddressDetails'(
    'ctrisId': 1473,
    'context': "Third Party Organisations associated with the trial",
    'addressLine1': "Address: Street name 2",
    'city': "Town/City 2",
    'postalCode': "12345",
    'country': "India",
    'phone': "12345"
    )
    )
    },
    'orgSPORId': "ORG-100005535"
    )
    }

    Based on the above code snippet, I need to delete the above highlighted rows.

    currently I'm using the below code to delete which is erroring out. Could you please provide me the proper code to achieve this requirement. 

  • 0
    Certified Associate Developer
    in reply to Stefan Helzle

    Hi stefan any update on this below requirement would be grateful, Please let me know if you need any other inputs.  

  • 0
    Certified Lead Developer
    in reply to sivakrishnam0002

    Could you post the for each part of your code please? Maybe you are iterating over the main array, but referencing the child one?

  • 0
    Certified Associate Developer
    in reply to David J (NTT DATA)

    a!forEach(
    ri!sponsorDetails,
    {
    a!localVariables(
    
    a!sectionLayout(
    label: "Sponsor " & fv!index,
    contents: {
    a!imageField(
    images: a!documentImage(
    document: a!iconIndicator("REMOVE"),
    altText: "Remove Sponsor",
    caption: "Remove Sponsor " & fv!item.sponsorName,
    link: a!dynamicLink(
    value: fv!index,
    saveInto: {
    if(
    isnull(fv!item.id),
    {},
    a!save(
    ri!deletedSponsorIds,
    append(ri!deletedSponsorIds, fv!item.id)
    )
    ),
    a!save(
    ri!sponsorDetails,
    remove(ri!sponsorDetails, save!value)
    ),
    if(
    or(
    a!isNullOrEmpty(ri!numberOfSponsorLegal),
    ri!numberOfSponsorLegal = 0
    ),
    {},
    a!save(
    ri!numberOfSponsorLegal,
    ri!numberOfSponsorLegal - 1
    )
    )
    }
    ),
    showWhen: not(
    ri!submissionType = cons!CTRIS_SUBMISSION_TYPES[4]
    )
    ),
    showWhen: not(ri!isReadOnly),
    size: "ICON",
    align: "END"
    ),
    {
    {
    a!localVariables(
    local!selectedTab: 1,
    {
    {
    choose(
    local!selectedTab,
    {
    a!boxLayout(
    label: "Add Third Party",
    contents: {
    a!cardLayout(
    contents: {
    a!sideBySideLayout(
    items: {
    a!sideBySideItem(
    item: a!richTextDisplayField(
    labelPosition: "COLLAPSED",
    value: {
    a!richTextIcon(icon: "info-circle", color: "#3d85c6")
    }
    ),
    width: "MINIMIZE"
    ),
    a!sideBySideItem(
    /* Replace this rich text with your warning message */
    item: a!richTextDisplayField(
    labelPosition: "COLLAPSED",
    value: {
    a!richTextItem(text: { "Note 1:" }, style: "STRONG"),
    " ",
    "For all studies, Add Third party details manually.",
    " "
    }
    )
    )
    },
    alignVertical: "MIDDLE",
    spacing: "STANDARD"
    ),
    a!sideBySideLayout(
    items: {
    a!sideBySideItem(
    item: a!richTextDisplayField(
    labelPosition: "COLLAPSED",
    value: {
    a!richTextIcon(icon: "info-circle", color: "#3d85c6")
    }
    ),
    width: "MINIMIZE"
    ),
    a!sideBySideItem(
    /* Replace this rich text with your warning message */
    item: a!richTextDisplayField(
    labelPosition: "COLLAPSED",
    value: {
    a!richTextItem(text: { "Note 2:" }, style: "STRONG"),
    " ",
    "Firstly, Third party needs to be registered in OMS. So, please make sure this third party details should match with Organisation Management System (OMS)",
    " "
    }
    )
    )
    },
    alignVertical: "MIDDLE",
    spacing: "STANDARD"
    )
    },
    showWhen: not(ri!isReadOnly),
    style: "WARN",
    marginBelow: "STANDARD",
    accessibilityText: "Warning message"
    ),
    a!buttonArrayLayout(
    buttons: {
    a!buttonWidget_23r3(
    label: "Add Third-Party Org Manually",
    saveInto: {
    a!save(
    fv!item.thirdPartyOrgDetails,
    append(
    fv!item.thirdPartyOrgDetails,
    {
    'type!{urn:com:appian:types:CTRIS}CTRIS_Part1_Sponsor_ThirdPartyOrg'(
    orgId: "",
    orgName: "",
    /*organizationType: fv!item.organization_type,*/
    tpAddress: 'type!{urn:com:appian:types:CTRIS}CTRIS_AddressDetails'(
    ctrisId: ri!ctrisId,
    context: "Third Party Organisations associated with the trial",
    addressLine1: "",
    city: "",
    postalCode: "",
    country: "",
    phone: "",
    email: "",
    updatedBy: loggedInUser(),
    updatedOn: now()
    ),
    ctrisId: ri!ctrisId,
    updatedBy: loggedInUser(),
    updatedOn: now()
    )
    }
    )
    )
    }
    )
    },
    align: "START"
    )
    },
    showWhen: not(ri!isReadOnly),
    style: "STANDARD",
    isCollapsible: true,
    padding: "NONE",
    marginBelow: "STANDARD"
    ),
    a!forEach(
    fv!item.thirdPartyOrgDetails,
    a!sectionLayout(
    label: " Third Party Organisation " & fv!index,
    labelSize: "SMALL",
    labelColor: "STANDARD",
    contents: {
    a!imageField(
    images: a!documentImage(
    document: a!iconIndicator("REMOVE"),
    altText: "Third Party Organisation",
    caption: "Third Party Organisation " & fv!index,
    link: a!dynamicLink(
    value: fv!index,
    saveInto: {
    a!save(
    fv!item.thirdPartyOrgDetails,
    remove(fv!item.thirdPartyOrgDetails, save!value)
    )
    }
    ),
    showWhen: not(
    ri!submissionType = cons!CTRIS_SUBMISSION_TYPES[4]
    )
    ),
    showWhen: not(ri!isReadOnly),
    size: "ICON",
    align: "END"
    ),
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!paragraphField(
    label: "Organisation ID",
    labelPosition: "ABOVE",
    value: fv!item.orgId,
    saveInto: {
    a!save(fv!item.orgId, left(save!value, 100)),
    a!save(fv!item.updatedBy, loggedInUser())
    },
    refreshAfter: "UNFOCUS",
    readOnly: ri!isReadOnly,
    validations: {},
    characterLimit: 100,
    showCharacterCount: true(),
    height: "SHORT",
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!paragraphField(
    label: "Name of organisation",
    labelPosition: "ABOVE",
    height: "SHORT",
    value: fv!item.orgName,
    saveInto: {
    a!save(fv!item.orgName, left(save!value, 150)),
    a!save(fv!item.updatedBy, loggedInUser())
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 150,
    readOnly: ri!isReadOnly,
    showCharacterCount: true,
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!localVariables(
    local!thirdPartyDuties: if(
    or(
    a!isNullOrEmpty(fv!item),
    a!isNullOrEmpty(fv!item.duties)
    ),
    {},
    split(fv!item.duties, ",")
    ),
    if(
    ri!isReadOnly = true(),
    rule!CTRIS_commonDropDownComponent(
    readOnly: ri!isReadOnly,
    fieldName: "Duties",
    selectedDataMultiple: fv!item.duties,
    isMultiSelect: true(),
    labelPosition: "ABOVE",
    isRequired: true(),
    choiceLabels: cons!CTRIS_SPONSOR_TRIAL_DUTIES,
    choiceValues: cons!CTRIS_SPONSOR_TRIAL_DUTIES
    ),
    {
    a!multipleDropdownField(
    label: "Duties",
    labelPosition: "ABOVE",
    placeholder: "--- Select ---",
    choiceLabels: cons!CTRIS_SPONSOR_TRIAL_DUTIES,
    choiceValues: cons!CTRIS_SPONSOR_TRIAL_DUTIES,
    value: { local!thirdPartyDuties },
    saveInto: {
    local!thirdPartyDuties,
    a!save(
    fv!item.duties,
    joinarray(local!thirdPartyDuties, ",")
    ),
    a!save(fv!item.updatedBy, loggedInUser()),
    a!save(fv!item.otherDescription, null)
    },
    searchDisplay: "AUTO",
    required: true(),
    disabled: ri!isReadOnly,
    validations: {}
    ),
    a!paragraphField(
    label: "Other Duties description",
    labelPosition: "ABOVE",
    value: fv!item.otherDescription,
    saveInto: fv!item.otherDescription,
    refreshAfter: "UNFOCUS",
    characterLimit: 4000,
    showCharacterCount: true(),
    height: "SHORT",
    readOnly: ri!isReadOnly,
    validationGroup: "character limit",
    showWhen: local!thirdPartyDuties="Other",
    required: local!thirdPartyDuties="Other",
    validations: {}
    )
    }
    )
    )
    }
    )
    }
    ),
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!paragraphField(
    label: "Address: Street name",
    labelPosition: "ABOVE",
    value: fv!item.tpAddress.addressLine1,
    saveInto: {
    a!save(
    fv!item.tpAddress.addressLine1,
    left(save!value, 75)
    ),
    a!save(
    fv!item.tpAddress.updatedBy,
    loggedInUser()
    ),
    a!save(
    fv!item.tpAddress.context,
    "Third Party Organisations associated with the trial"
    )
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 75,
    readOnly: ri!isReadOnly,
    validations: {},
    height: "SHORT"
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!paragraphField(
    label: "Town/City",
    labelPosition: "ABOVE",
    height: "SHORT",
    value: fv!item.tpAddress.city,
    saveInto: {
    a!save(
    fv!item.tpAddress.city,
    left(save!value, 75)
    ),
    a!save(
    fv!item.tpAddress.updatedBy,
    loggedInUser()
    ),
    a!save(
    fv!item.tpAddress.context,
    "Third Party Organisations associated with the trial"
    )
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 75,
    readOnly: ri!isReadOnly,
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!paragraphField(
    label: "Post Code",
    labelPosition: "ABOVE",
    value: fv!item.tpAddress.postalCode,
    saveInto: {
    a!save(
    fv!item.tpAddress.postalCode,
    left(save!value, 75)
    ),
    a!save(
    fv!item.tpAddress.updatedBy,
    loggedInUser()
    ),
    a!save(
    fv!item.tpAddress.context,
    "Third Party Organisations associated with the trial"
    )
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 75,
    readOnly: ri!isReadOnly,
    validations: {},
    height: "SHORT"
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!paragraphField(
    label: "Country",
    labelPosition: "ABOVE",
    height: "SHORT",
    value: fv!item.tpAddress.country,
    saveInto: {
    a!save(
    fv!item.tpAddress.country,
    left(save!value, 128)
    ),
    a!save(
    fv!item.tpAddress.updatedBy,
    loggedInUser()
    ),
    a!save(
    fv!item.tpAddress.context,
    "Third Party Organisations associated with the trial"
    )
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 128,
    readOnly: ri!isReadOnly,
    validations: {}
    )
    }
    )
    }
    ),
    a!columnsLayout(
    columns: {
    a!columnLayout(
    contents: {
    a!textField(
    label: "Telephone number",
    labelPosition: "ABOVE",
    value: stripwith(
    fv!item.tpAddress.phone,
    "`~!@#$%^&*()_-={[}}\|;:'<>,.?/qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
    ),
    saveInto: {
    a!save(
    fv!item.tpAddress.phone,
    stripwith(
    left(save!value, 15),
    "`~!@#$%^&*()_-={[}}\|;:'<>,.?/qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
    )
    ),
    a!save(
    fv!item.tpAddress.updatedBy,
    loggedInUser()
    ),
    a!save(
    fv!item.tpAddress.context,
    "Third Party Organisations associated with the trial"
    )
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 15,
    readOnly: ri!isReadOnly,
    validations: {}
    )
    }
    ),
    a!columnLayout(
    contents: {
    a!textField(
    label: "Email address",
    labelPosition: "ABOVE",
    value: fv!item.tpAddress.email,
    saveInto: {
    a!save(
    fv!item.tpAddress.email,
    left(save!value, 100)
    ),
    a!save(
    fv!item.tpAddress.updatedBy,
    loggedInUser()
    ),
    a!save(
    fv!item.tpAddress.context,
    "Third Party Organisations associated with the trial"
    )
    },
    refreshAfter: "UNFOCUS",
    characterLimit: 100,
    readOnly: ri!isReadOnly,
    validations: {}
    )
    }
    )
    }
    )
    }
    )
    )
    }
    )
    }
    }
    )
    }
    }
    },
    isCollapsible: true,
    divider: "BELOW",
    dividerColor: "STANDARD"
    )
    )
    }
    ),



    Hi   Please find the attached code snippet you have requested. Let me know if you have any questions.

  • 0
    Certified Lead Developer
    in reply to sivakrishnam0002

    Replace the document image with one paragrapph field, in order to check the values contained in the second for each...

    Maybe the problem is related with the nested for each... Sometimes with nested for eachs, appian does not work as we expect

  • 0
    Certified Lead Developer
    in reply to sivakrishnam0002

    In that foreach you iterate on thirdPartyOrgDetails. Then, inside that foreach where fv!item is such a thirdPartyOrgDetail, you try to delete something. That is exactly what the error message tries to explain.