0
votes

Summary of the problem -

I am using ag-grid-angular with server-side row model to lazy load the tree data. But I am having 2 different API calls to load the parent data and child data. The issue is when I expand and collapse the parent rows multiple times the rowData gets messed up like some blank space is seen and the expand collapse also does not work properly.

What I already tried - I debugged the code and found that on expanding any parent row for the first time a backend call happens to load child rows but next time when I expand the same parent it takes the child details from the cache. Also, there is a duplication of rowIndex between parent and child rows. I also tried to Purge Cache but it did not work.

Code - My code is similar to what is given in this URL. Just the difference is that we have a real server and data is fetched dynamically from 2 different API calls for parent and child rows. Whereas in the example given on URL, they have a single data.json file from which both parent and child rows are loaded with some timeout.

The code looks somewhat like below - HTML looks like below:

<ag-grid-angular
            #agGrid class="ag-theme-fresh ag-fresh"
            [gridOptions]="agGridOptions"
            [columnDefs]="columnDefs"
            [defaultColDef]="defaultColDef"
            [autoGroupColumnDef]="autoGroupColumnDef"
            [rowModelType]="rowModelType"
            [treeData]="true"
            [animateRows]="true"
            [isServerSideGroup]="isServerSideGroup"
            [getServerSideGroupKey]="getServerSideGroupKey"
            (gridReady)="onGridReady($event)"
          ></ag-grid-angular>

TS file - //Setting Grid Options:

        this.agGridOptions = {
              pagination: true,
              paginationPageSize: 100,
              rowHeight: 40,
              columnDefs: [],
              headerHeight: 45,
              suppressContextMenu: true,
              enableSorting: true,
              icons: {
                groupExpanded: '<span class="ag-icon ag-icon-small-down"></span>',
                groupContracted: '<span class="ag-icon ag-icon-small-right"></span>'
              }
            };

            this.columnDefs = agGridConfig.columnDefs;
            this.defaultColDef = {
              filter: true,
              sortable: true,
              resizable: true
            };
            this.autoGroupColumnDef = {
              headerName: 'Name',
              field: 'name',
              width: 350
            };
            this.rowModelType = "serverSide";
            this.isServerSideGroup = function (item) {
              return item.group;
            };
            this.stateService.register('grids', this.gridOptions.name);
            this.getServerSideGroupKey = function (item) {
              let childParam: any = {
                id: item.id,
                date: item.date
              };
              return childParam;
            };

        onGridReady(params: GridOptions) {
            this.agGridRef = params;
            let datasource = this.createServerSideDatasource(this.apiService);
            params.api.setServerSideDatasource(datasource);
          }

        createServerSideDatasource(apiService: ApiService) {
            function ServerSideDatasource(apiService: ApiService) {
              this.apiService = apiService;
            }

            ServerSideDatasource.prototype.getRows = (params) => {
              let parentDataset: any;
              let queryParam: any;
              if (params.request.groupKeys && params.request.groupKeys.length > 0) {
                let parDataSets: any = params.request.groupKeys;
                if (parDataSets && parDataSets.length > 1) {
                  parentDataset = parDataSets[ parDataSets.length - 1 ];
                } else {
                  parentDataset = parDataSets[ 0 ];
                }
                queryParam = this.service.getChildParams(parentDataset);
                apiService.get<any, any>(‘childDatasetURL’, queryParam).subscribe(response => {
                  let rows = response.data;
                  params.successCallback(rows, rows.length);
                });
              } else {
                this.showSpinner = true;
                queryParam = this.service.getParentParams();
                apiService.get<any, any>('parentDatasetURL’, queryParam).subscribe(response => {
                  let rows = response.data;
                  params.successCallback(rows, rows.length);
                  this.showSpinner = false;
                });
              }
            };
            return new ServerSideDatasource(apiService);
          }

    ParentDatasetURL.json - {
          "messages": [],
          "data": [
            {
              "id": 1,
              "name": "parent1"
            },
            {
              "id": 2,
              "name": "parent2"
            }
          ]
        }
    ChildDatasetURL.json - {
          "messages": [],
          "data": [
            {
              "id": 3,
              "name": "parent1child"
            },
            {
              "id": 4,
              "name": "parent2child"
            }
          ]
        }

Actual Result - The tree data expands and collapses fine for first few times but later it does not expand and collapse properly and the rowData shows some blank space in between and rowIndex is all messed up.

Expected Result - The parent should expand properly to lazy load the child data even when opened multiple times. Also on collapsing the rows, the rowData should close properly without any mess.

1
Can you provide Stackblitz?Prashant Pimpale

1 Answers

0
votes

I experienced the same issue.

I found that it was due to the value returned in getServerSideGroupKey being not unique. After ensuring that that value was truly unique for all rows, the problem was resolved.