Get current object

Here is my expression:

a!localVariables(
  /* Loop checks against passed in value of type to pull values
     from specific requirementActivity match */
  a!forEach(
    items: ri!requirement.requirementActivities, 
    expression: 
    if(contains(ri!activityType, fv!item.type),
    'type!{urn:com:appian:types:UW}UW-Requirement-Activity'(
      key: fv!item.key,
      type: fv!item.type,
      creatorId: fv!item.creatorId,
      creatorFullName: fv!item.creatorFullName,
      createdDate: fv!item.createdDate,
      commentText: fv!item.commentText
    ), 
    {}), 
  ),
),

activityType is Text Array
snippet of rule in play:
local!requirements: {
        a!forEach(
          items: local!requirementsResponse,
          expression: a!localVariables(
            local!receivedRequirementActivity: rule!UW_GetRequirementActivityByType(
              requirement: fv!item,
              activityType:  "RECEIVED"
            ),
            local!waivedOrAcceptedRequirementActivity: rule!UW_GetRequirementActivityByType(
              requirement: fv!item,
              activityType: {
                "WAIVED",
                "ACCEPTED"
              }
            ),
            a!map(
              type: property(
                fv!item,
                "name",
                {}
              ),
              status: property(
                fv!item,
                "status",
                {}
              ),
              orderDate: property(
                fv!item,
                "createdTimestamp",
                {}
              ),
              orderRep: property(
                fv!item,
                "requestedBy",
                {}
              ),
              receiveDate: property(
                local!receivedRequirementActivity,
                "createdDate",
                {}
              ),
              receiveRep: property(
                local!receivedRequirementActivity,
                "creatorFullName",
                {}
              ),

It works great unless their are duplicate ActivityTypes - I need to return the current ActivityType and I'm rather new to Appian development and having a time sorting out how to handle this. What is currently happening is the fields: creatorFullName: fv!item.creatorFullName & createdDate: fv!item.createdDate in my table are populating every associated date and creator returned that's associated with the activityType. 

I've been searching the docs and I'm just not really finding a direction to go. Any guidance would be greatly appreciated.

  Discussion posts and replies are publicly visible

  • Can you describe from a higher level what you're trying to accomplish? 

  • I am populating an interface grid with data being called from our api - I am successfully sorting an array of objects by type "activityType" and displaying related data to the in the grid. However when we have objects with the same type the grid is being populated with all createdDates and CreaorFullName that matches that type. Example of what is occurring (this is sample data) So in this instance below I had 3 activities with the same TYPE of RECEIVED resulting in the below. 

  • 0
    Appian Employee
    in reply to seenaomi

    Can you describe your data model? From what you're saying, it sounds to me like you have a 1:M relationship between the source record and some of the data displayed in your columns for Date Received and Received By. If that's the case, do you want to display all of the related records or only a subset? Also could you post the expression of the entire grid instead of only the snippets above?

  • {
      {
        a!localVariables(
          requirementsResponse: rule!UW_GetRequirementsByCase_RDS(
            caseKey: ri!caseKey, 
            queryType: null, 
            assigneeId: null
          ),
          local!requirements: {
            a!forEach(
              items: local!requirementsResponse,
              expression: a!localVariables(
                local!receivedRequirementActivity: rule!UW_GetRequirementActivityByType(
                  requirement: fv!item,
                  activityType:  "RECEIVED"
                ),
                local!waivedOrAcceptedRequirementActivity: rule!UW_GetRequirementActivityByType(
                  requirement: fv!item,
                  activityType: {
                    "WAIVED",
                    "ACCEPTED"
                  }
                ),
                a!map(
                  type: property(
                    fv!item,
                    "name",
                    {}
                  ),
                  status: property(
                    fv!item,
                    "status",
                    {}
                  ),
                  orderDate: property(
                    fv!item,
                    "createdTimestamp",
                    {}
                  ),
                  orderRep: property(
                    fv!item,
                    "requestedBy",
                    {}
                  ),
                  receiveDate: property(
                    local!receivedRequirementActivity,
                    "createdDate",
                    {}
                  ),
                  receiveRep: property(
                    local!receivedRequirementActivity,
                    "creatorFullName",
                    {}
                  ),
                  resolveDate: property(
                    local!waivedOrAcceptedRequirementActivity,
                    "createdDate",
                    {}
                  ),
                  resolveRep: property(
                    local!waivedOrAcceptedRequirementActivity,
                    "creatorFullName",
                    {}
                  ),
                  resolutionStatus: property(
                    local!waivedOrAcceptedRequirementActivity,
                    "type",
                    {}
                  ),
                  resolutionNotes: property(
                    local!waivedOrAcceptedRequirementActivity,
                    "commentText",
                    {}
                  )
                )
              )
            )
          },
          /* This variable is used to pass the full row of data on the selected item to the part of the interface showing the details of the selected item. */
          /* Here we are pre-selecting a row by indexing into the sample data; however, the data for the pre-selected row would typically be passed in as a *
           * rule input or generated with a query.                                                                                                          */
          local!selectedRequirements: local!requirements[1],
          {
            a!richTextDisplayField(
              labelPosition: "COLLAPSED",
              value: {
                a!richTextItem(
                  text: {
                    "Requirements"
                  },
                  color: "ACCENT",
                  size: "MEDIUM_PLUS",
                  style: {
                    "STRONG"
                  }
                )
              }
            ),
            a!columnsLayout(
              columns: {
                a!columnLayout(
                  contents: {
    
                    a!gridField(
                      /* Replace the dummy data with a query, rule, or function that returns a datasubset and uses fv!pagingInfo as the paging configuration. */
                      data: todatasubset(
                        local!requirements,
                        fv!pagingInfo
                      ),
                      columns: {
                        a!gridColumn(
                          label: "Requirement Type",
                          value: fv!row.type
                        ),
                        a!gridColumn(
                          label: "Date Ordered",
                          value: fv!row.orderDate
                        ),
                        a!gridColumn(
                          label: "Ordered By",
                          value: fv!row.orderRep
                        ),
                        a!gridColumn(
                          label: "Date Received",
                          value: fv!row.receiveDate
                        ),
                        a!gridColumn(
                          label: "Received By",
                          value: fv!row.receiveRep
                        ),
                        a!gridColumn(
                          label: "Date Completed",
                          value: fv!row.resolveDate
                        ),
                        a!gridColumn(
                          label: "Completed By",
                          value: fv!row.resolveRep
                        ),
                        a!gridColumn(
                          label: "Completed Status",
                          value: fv!row.resolutionStatus
                        ),
                        a!gridColumn(
                          label: "Comments",
                          value: fv!row.resolutionNotes
                        )
                      },
                      pageSize: 7,
                      selectable: true,
                      selectionStyle: "ROW_HIGHLIGHT",
                      selectionValue: index(local!selectedRequirements, "id", {}),
                      selectionSaveInto: {
                        /* This save replaces the value of the previously selected item with that of the newly selected item, ensuring only one item can be selected at once.*/
                        a!save(
                          local!selectedRequirements,
                          if(
                            length(fv!selectedRows) > 0,
                            fv!selectedRows[length(fv!selectedRows)],
                            null
                          )
                        )
                      },
                      shadeAlternateRows: false,
                      rowHeader: 1
                    )
                  }
    
                )
              },
              stackWhen: {
                "PHONE",
                "TABLET_PORTRAIT"
              }
            )
          }
        )
      }
    }

    entire grid ^^

    We do have a 1:M relationship but some can be created multiple times we are handling with validation on the backend. 

    We have UW case with requirements and requirement activities are essentially actions that have been taken place associated with a particular requirement. In this case I am sorting and pulling data from 3 activityTypes: RECEIVED, WAIVED, and ACCEPTED. I just need to be sure to populated the related grid fields with the most current data associated with the related type (not all).

  • It appears your issue is that for one of the items in the row you get an array of dates received. You might want to modify the way you build your list of local!requirements to account for that. If you do not need the additional data (you mention that you want to show the most recent data), you might want to modify it as early as GetRequirementsByCaseId to throw away older actions taken.

    As a sidenote: Can I suggest you analyse your interface for performance some time down the line? Assuming "GetRequirementActivityByType" queries data from somewhere, you'd end up with n*2 DB queries to load the grid, which can slow things down a lot.

  • I understand what the issue is, thank you. :) I  am asking for guidance specifically in the appian way on how to modify to throw away what I don't need. Thank you for your suggestion around performance. Data is coming from our api and typically a case wouldn't have 86 + requirements associated we are in development and working with test data resulting in a bloated impression of reality.

  • Don't let it come into the list that you're displaying. For example, modify the rule that retrieves the requirements for you to only give you the most recent one (that you want to see).

  • yes but how - I understand logically - can you guide me to docs that provide guidance on how to accomplish this? That is what I am asking for here. :)

  • +1
    Appian Employee
    in reply to seenaomi

    I'd suggest doing a few steps:

    1. Move your queries up out of the a!forEach() for local!requirements into the top level and query all the requirement activity for all requirementResponses so that you're only running one query instead of one for each response. This should improve the performance by reducing the number of queries executed.
    2. Update your local!requirementsResponse within the a!forEach() to return the requirements that relate to the given response. I typically do this using the displayvalue() function because it allows you to match an item from your response to your activity list.
    3. At this point you're still likely returning a list of values for each response and you need to return only the most recent. I'd use the index() function to return only the first item from each list to ensure you only display one value.

    I know that's a pretty high level, but hopefully that at least can get you started - of course feel free to ask any questions as you're going!

    One other thing to mention - my suggestion was primarily for keeping the same data model as you currently have. If you are using something like synced records it would actually be much easier to do this because there is a function for a!relatedRecordData() that lets you directly define the properties for your activites. Some app developers also prefer to set up this logic in a database view, because you can use any of the functions that SQL offers to get your data in the format you need.