Grid error: totalCount must not be null or less than the number of items

Hi all,

A user got a UI expression error today that reads "[...] has an invalid value for "totalCount". "totalCount" must not be null or less than the number of items in any of the "data" arrays, but "totalCount" was 0 and the largest column data array had 1 items."

I'm unable to replicate the UI error and unable to see what could be causing it. I've been looking through the forums and have checked that when there's no data being passed in, no data should be getting generated for any of the columns. Where possible they all either index {} when null or use a foreach, which from what I've read should prevent this type of error from occurring. 

I've attached the code for the grid, I apologize for the length. If anyone manages to take a look and indicate what the issue might be I'd really appreciate it.

      a!gridField_19r1(
        spacing: "DENSE",
        showWhen: not(
          rule!CMN_isEmpty(
            local!datasubset
          )
        ),
        label: " ",
        emptyGridMessage: "There are no tasks based on the selected filters.",
        totalCount: local!datasubset.totalCount,
        columns: {
          a!gridTextColumn(
            label: "Date added",
            field: "createdOn",
            data: a!forEach(
              index(
                local!datasubset,
                "data",
                {}
              ),
              rule!CMN_formatDateTime(
                returnDateOnly: true,
                dateTime: index(
                  fv!item,
                  "createdOn",
                  {}
                )
              )
            )
          ),
          a!gridTextColumn(
            label: "Age",
            field: "workitemAge",
            data: index(
              index(
                local!datasubset,
                "data",
                {}
              ),
              "workitemAge",
              {}
            )
          ),
          a!gridTextColumn(
            label: "Work item ID",
            field: "workflowId",
            data: index(
              index(
                local!datasubset,
                "data",
                {}
              ),
              "workflowId",
              {}
            ),
            links: a!forEach(
              items: index(
                local!datasubset,
                "data",
                {}
              ),
              expression: if(
                rule!CMN_isBlank(
                  index(
                    index(
                      index(
                        ri!taskDatasubset,
                        "data",
                        null
                      ),
                      "c6",
                      null
                    ),
                    wherecontains(
                      tointeger(
                        fv!item.workflowId
                      ),
                      tointeger(
                        index(
                          index(
                            ri!taskDatasubset,
                            "data",
                            null
                          ),
                          "c5",
                          null
                        )
                      )
                    ),
                    null
                  )
                ),
                "",
                a!processTaskLink(
                  task: index(
                    index(
                      index(
                        ri!taskDatasubset,
                        "data",
                        null
                      ),
                      "c6",
                      null
                    ),
                    wherecontains(
                      tointeger(
                        fv!item.workflowId
                      ),
                      tointeger(
                        index(
                          index(
                            ri!taskDatasubset,
                            "data",
                            null
                          ),
                          "c5",
                          null
                        )
                      )
                    ),
                    null
                  )
                )
              )
            )
          ),
          a!gridTextColumn(
            label: "ID",
            field: "aId",
            data: index(
              index(
                local!datasubset,
                "data",
                {}
              ),
              "aId",
              {}
            )
          ),
          a!gridTextColumn(
            label: "Work item type",
            field: "workflowTypeLabel",
            data: index(
              index(
                local!datasubset,
                "data",
                {}
              ),
              "workflowTypeLabel",
              {}
            )
          ),
          a!gridTextColumn(
            label: "Status",
            field: "workflowStatusLabel",
            data: index(
              index(
                local!datasubset,
                "data",
                {}
              ),
              "workflowStatusLabel",
              {}
            )
          ),
          a!gridTextColumn(
            label: "Party 1",
            field: "partyId",
            data: a!forEach(
              items: index(
                index(
                  local!datasubset,
                  "data",
                  {}
                ),
                "partyId",
                {}
              ),
              expression: rule!getCurrentPartyNameFromList(
                currentItem: fv!item
              )
            )
          ),
          a!gridTextColumn(
            label: "Party Name",
            field: "partyName",
            data: a!forEach(
              items: index(
                index(
                  local!datasubset,
                  "data",
                  {}
                ),
                "partyName",
                {}
              ),
              expression: rule!getCurrentPartyNameFromList(
                currentItem: fv!item
              )
            )
          ),
          a!gridTextColumn(
            label: "type",
            field: "Type",
            data: a!forEach(
              index(
                local!datasubset,
                "data",
                {}
              ),
              index(
                fv!item,
                "type",
                {}
              )
            )
          ),
          a!gridTextColumn(
            label: "Is group?",
            field: "isGroupMaster",
            data: a!forEach(
              index(
                local!datasubset,
                "data",
                {}
              ),
              if(
                toboolean(
                  index(
                    fv!item,
                    "isGroupMaster",
                    {}
                  )
                ) = true,
                "Yes",
                "No"
              )
            )
          ),
          a!gridTextColumn(
            label: "Assignee",
            field: "currentAssignee",
            data: a!forEach(
              index(
                index(
                  local!datasubset,
                  "data",
                  {}
                ),
                "currentAssignee",
                {}
              ),
              rule!CMN_formatUserName(
                username: fv!item
              )
            )
          ),
          a!gridTextColumn(
            label: "Decision Maker",
            field: "decisionMaker",
            data: a!forEach(
              index(
                index(
                  local!datasubset,
                  "data",
                  {}
                ),
                "decisionMaker",
                {}
              ),
              rule!CMN_formatUserName(
                username: fv!item
              )
            )
          ),
          a!gridTextColumn(
            label: "Local entity",
            field: "localPartyName",
            data: a!forEach(
              items: index(
                index(
                  local!datasubset,
                  "data",
                  {}
                ),
                "localPartyName",
                {}
              ),
              expression: rule!getCurrentPartyNameFromList(
                currentItem: fv!item
              )
            )
          )
        },
        identifiers: index(
          index(
            local!datasubset,
            "data",
            {}
          ),
          "workflowId",
          {}
        ),
        value: ri!gridSelection,
        saveInto: {
          ri!gridSelection,
          if(
            rule!CMN_isEmpty(
              ri!gridSelection.selected
            ),
            a!save(
              ri!selectedWorkflowObject,
              {}
            ),
            {
              a!save(
                local!unselectedWorkflows,
                difference(
                  touniformstring(
                    index(
                      ri!selectedWorkflowObject,
                      "workflowId",
                      null
                    )
                  ),
                  touniformstring(
                    ri!gridSelection.selected
                  )
                )
              ),
              a!save(
                local!selectedWorkflows,
                difference(
                  touniformstring(
                    ri!gridSelection.selected
                  ),
                  touniformstring(
                    index(
                      ri!selectedWorkflowObject,
                      "workflowId",
                      null
                    )
                  )
                )
              ),
              a!save(
                ri!selectedWorkflowObject,
                if(
                  rule!CMN_isEmpty(
                    local!unselectedWorkflows
                  ),
                  ri!selectedWorkflowObject,
                  remove(
                    ri!selectedWorkflowObject,
                    wherecontains(
                      local!unselectedWorkflows,
                      touniformstring(
                        index(
                          ri!selectedWorkflowObject,
                          "workflowId",
                          null
                        )
                      )
                    )
                  )
                )
              ),
              a!save(
                ri!selectedWorkflowObject,
                if(
                  rule!CMN_isEmpty(
                    local!selectedWorkflows
                  ),
                  ri!selectedWorkflowObject,
                  append(
                    ri!selectedWorkflowObject,
                    index(
                      local!datasubset.data,
                      wherecontains(
                        local!selectedWorkflows,
                        touniformstring(
                          index(
                            local!datasubset.data,
                            "workflowId",
                            null
                          )
                        )
                      ),
                      null
                    )
                  )
                )
              )
            }
          )
        },
        selection: true(),
        shadeAlternateRows: true()
      )

  Discussion posts and replies are publicly visible

Parents
  • +1
    Certified Lead Developer

    I agree with the troubleshooting advice supplied above by Krishna.  To clarify -- it seems that at least one of your columns is returning NULL or another non-empty value even when the total count is zero.  In most places I can see you have correctly returned an empty set "{}" when there's no data, but my assumption is that you've missed something in one of the columns.

    BTW, I can tell you're already on version 19.2 or higher - the paging grid component was completely overhauled as of 19.2 and is now a lot easier to configure overall, including not having to worry quite so much about the empty set condition in every single column definition anymore.  This might be a good time to switch over to using that, instead of spending a lot of effort to try to fix your current version (unless you really just want to know what the issue was).

  • Thanks for the advice  and  unfortunately the issue only occurred briefly on our PROD environment and I can't replicate it in the DEV environment, so I can't reproduce a scenario where I can start debugging it further in this way. 
    Could it possibly be an intermittent issue where some of the column data isn't refreshed correctly/in time? It only occurred when the user tried to submit a work item to another user. The data is populated in the parent interface from a dashboard view, within a with() within a localvariables() call. This is then passed into the sub interface, and assigned to a local variable within in a with() within a load().
    I don't know if any of this could be causing an issue but I'm going to look at removing the localvariables(with()) call in the parent and the load(with()) in the sub interfaces and replace them both with a single localvariables() in each, and also look at updating the grid component as suggested by you . Any other suggestions that might be worth looking into? Thanks again for the help.

  • 0
    Certified Lead Developer
    in reply to johng0005

    I've seen a similar error message in the past when populating a paging grid from a view where the primary key column doesn't end up being unique -- meaining sometimes the totalCount will come back lower than the number of rows returned (since the totalCount won't include duplicates on the primary key).  However I'm not sure how that would apply to your case where there are apparently 0 rows.  But hopefully that might provide at least a bit of additional insight.

    That being said - i completely agree with your decision to remove the unnecessary nested local variable containers.  a!localVariables fully replaces both load() and with(), and under normal circumstances should never need to be nested like load(with()) were.  Also when replacing the original grid, my recommendation from experience so far is to build a new one right above the old one, and get it working before removing the old one (as opposed to trying to change over the internal values of the old one).

  • Cheers for the recommendations Mike, I checked the view and it all seems good but it wasn't something that had crossed my mind before, so thanks for the tip. One last question, I've checked the documentation but is there any best practices/anything I should be aware of for the new grid component? I've noticed the data is added to each column with a simple fv!row.[fieldName], do I need to do something similar with the new grid version in regards to using an a!forEach or an index to return blank values? Thanks again for taking the time to help out with this.

  • +1
    Certified Lead Developer
    in reply to johng0005

    So far when using the new grid component, I've found that it handles the "empty" condition pretty nicely, and automatically - so it should be fine to just call fv!row.propertyName instead of wrapping it in the property() function (which should be used instead of index() when accessing a CDT property, if just for code clarity).

  • 0
    Certified Associate Developer
    in reply to Mike Schmitt

    THANK YOU!!!!!!!!!!!!

    THANK YOU!!!!!!!!!!!!

    THANK YOU!!!!!!!!!!!!

    THANK YOU!!!!!!!!!!!!

    THANK YOU!!!!!!!!!!!!

    It was duplicates from a VIEW (Bad Data in QA env)

    THANK YOU!!!!!!!!!!!!

    THANK YOU!!!!!!!!!!!!

    THANK YOU!!!!!!!!!!!!

Reply Children
No Data