AgGrid React v25.3 getRows keeps firing even when all rows are already loaded

I have created AgGridReact component with a server-side data source.

Everything worked fine with v24, but I have updated the library to its latest version (v25.3) and now the grid just keeps loading data without displaying it.

I have updated the code as shown on ag-grid’s official page (https://blog.ag-grid.com/upgrading-to-ag-grid-v25-server-side-row-model/) but it did not help.

import React, { useRef } from 'react';
import { AxiosResponse } from 'axios';
import { AgGridReact } from '@ag-grid-community/react';
import {
  AllModules,
  ColumnApi,
  GridReadyEvent,
  IServerSideGetRowsParams,
  ModelUpdatedEvent,
  GridApi,
  ColDef,
  ToolPanelVisibleChangedEvent,
  ServerSideStoreType,
} from '@ag-grid-enterprise/all-modules';
import { Box } from '@material-ui/core';
import { CellRenderer, GridActions, GridColumn, GridContext } from './types';
import { columnTypes, defaultColDef, sideBarDef } from './config';
import { parseSortModel, parseFilterModel } from './parsers';
import { ListRequestParams, ScrollableEntry } from '../../api/types';

import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-material.css';
import { gridActionColumn } from './columns';
import { ActionCellRenderer } from './ActionCellRenderer';

interface Props<T> {
  rows?: T[];
  actions?: GridActions<T>;
  columns: Array<GridColumn<T>>;
  onRowsFetch?(params: ListRequestParams): Promise<AxiosResponse<ScrollableEntry<T>>>;
}

export const DataGrid = <T extends unknown>({
  rows,
  actions,
  columns,
  onRowsFetch,
}: React.PropsWithChildren<Props<T>>) => {
  const gridApi = useRef<GridApi>();
  const gridColumnApi = useRef<ColumnApi>();
  const lastRow = useRef<number>(0);

  const columnDefs = actions ? [...(columns as ColDef[]), gridActionColumn] : (columns as ColDef[]);
  const context: GridContext<T> = { actions };

  return (
    <Box maxHeight="60vh" width="100%" boxSizing="border-box" className="ag-theme-material">
      <AgGridReact
        modules={AllModules}
        popupParent={document.body}
        defaultColDef={defaultColDef}
        frameworkComponents={{ [CellRenderer.Action]: ActionCellRenderer }}
        context={context}
        rowData={rows}
        rowModelType={onRowsFetch ? 'serverSide' : 'clientSide'}
        serverSideStoreType={ServerSideStoreType.Partial}
        serverSideDatasource={{ getRows }}
        cacheBlockSize={100}
        blockLoadDebounceMillis={500}
        maxBlocksInCache={2}
        suppressContextMenu
        colResizeDefault="shift"
        columnDefs={columnDefs}
        columnTypes={columnTypes.reduce((ac, a) => ({ ...ac, [a]: {} }), {})}
        onGridReady={onGridReady}
        onModelUpdated={resizeColumns}
        onGridSizeChanged={resizeColumns}
        onToolPanelVisibleChanged={resizeColumns}
        suppressMovableColumns
        suppressColumnMoveAnimation
        sideBar={sideBarDef}
        suppressMenuHide
        alwaysShowVerticalScroll
      />
    </Box>
  );

  function onGridReady({ api, columnApi }: GridReadyEvent) {
    gridApi.current = api;
    gridColumnApi.current = columnApi;
    api.sizeColumnsToFit();
    api.setFilterModel({});
  }

  function resizeColumns({ api }: ModelUpdatedEvent | ToolPanelVisibleChangedEvent) {
    api.sizeColumnsToFit();
  }

  async function getRows({ request, success, fail }: IServerSideGetRowsParams) {
    if (!onRowsFetch) {
      return;
    }

    try {
      const lastPageLoadedBefore = request.endRow >= lastRow.current && lastRow.current !== 0;
      const result = await onRowsFetch({
        startRow: request.startRow,
        endRow: lastPageLoadedBefore ? lastRow.current : request.endRow,
        sort: parseSortModel(request.sortModel),
        filter: parseFilterModel(request.filterModel),
      });
      lastRow.current = result.data.lastRow ?? 0;
      const lastPageLoadedNow = request.endRow >= lastRow.current;
      success({
        rowData: result.data.content,
        rowCount: lastPageLoadedNow ? lastRow.current : -1,
      });
    } catch (error) {
      fail();
      throw error;
    }
  }
};

When I open the page with this component, responses look like this:

1st load

content: [,…]
endRow: 100
lastRow: 1
startRow: 0

2nd load:

content: [,…]
endRow: 1
lastRow: 1
startRow: 0

3rd and every other load until I close the page:

content: [,…]
endRow: 1
lastRow: 1
startRow: 0

Why is the grid keep loading data even though it has reached its last row? I have tried changing success callback’s rowCount parameter to 1, 0, -1 or any other number but the issue persists. What am I missing?

Source: Ask Javascript Questions

LEAVE A COMMENT