---
title: "SSRM Row Height"
enterprise: true
framework: javascript
version: "36.1.0"
---

# SSRM Row Height

Learn how to set Row Height when using the Server-Side Row Model.

## Dynamic Row Height

To enable [Dynamic Row Height](https://www.ag-grid.com/javascript-data-grid/row-height/) when using the Server-Side Row Model you need to provide an implementation for the `getRowHeight` Grid Options property. This is demonstrated in the example below:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `getRowHeight` | `GetRowHeight` |  |  | Callback version of property `rowHeight` to set height for each row individually. Function should return a positive number of pixels, or return `null`/`undefined` to use the default row height. |

#### Dynamic Row Height Example

```ts
import {
  GridApi,
  GridOptions,
  IServerSideDatasource,
  ModuleRegistry,
  RowHeightParams,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  RowGroupingModule,
  ServerSideRowModelModule,
} from "ag-grid-enterprise";
import { FakeServer } from "./fakeServer";
import { IOlympicData } from "./interfaces";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([RowGroupingModule, ServerSideRowModelModule]);

let gridApi: GridApi<IOlympicData>;
const gridOptions: GridOptions<IOlympicData> = {
  columnDefs: [
    { field: "country", rowGroup: true, hide: true },
    { field: "year", rowGroup: true, hide: true },
    { field: "gold", aggFunc: "sum" },
    { field: "silver", aggFunc: "sum" },
    { field: "bronze", aggFunc: "sum" },
  ],
  defaultColDef: {
    flex: 1,
    minWidth: 100,
  },
  autoGroupColumnDef: {
    flex: 1,
    minWidth: 180,
  },
  // use the server-side row model
  rowModelType: "serverSide",

  // dynamically set row heights
  getRowHeight: (params: RowHeightParams) => {
    if (params.node.level === 0) {
      return 80;
    }
    if (params.node.level === 1) {
      return 60;
    }
    return 40;
  },

  suppressAggFuncInHeader: true,
};

function getServerSideDatasource(server: any): IServerSideDatasource {
  return {
    getRows: (params) => {
      console.log("[Datasource] - rows requested by grid: ", params.request);

      const response = server.getData(params.request);

      // adding delay to simulate real server call
      setTimeout(() => {
        if (response.success) {
          // call the success callback
          params.success({
            rowData: response.rows,
            rowCount: response.lastRow,
          });
        } else {
          // inform the grid request failed
          params.fail();
        }
      }, 200);
    },
  };
}

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then(function (data) {
    // setup the fake server with entire dataset
    const fakeServer = new FakeServer(data);

    // create datasource with a reference to the fake server
    const datasource = getServerSideDatasource(fakeServer);

    // register the datasource with the grid
    gridApi!.setGridOption("serverSideDatasource", datasource);
  });
```

[Live example: Dynamic Row Height Example](https://www.ag-grid.com/examples/server-side-model-row-height/dynamic-row-height/typescript/)

> **Note**
>
> Ensure `maxBlocksInCache` is not set when using dynamic row height.

## Auto Row Height

To have the grid calculate the row height based on the cell contents, set `autoHeight=true` on columns that require variable height. The grid will calculate the height once when the data is loaded into the grid.

In the example below, Column A & B have `autoHeight=true` and `wrapText=true`. See [Row Height](https://www.ag-grid.com/javascript-data-grid/row-height/) for details on these properties.

#### Auto Row Height Example

```ts
import {
  ColDef,
  GridApi,
  GridOptions,
  IServerSideDatasource,
  ModuleRegistry,
  RowAutoHeightModule,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  RowGroupingModule,
  ServerSideRowModelModule,
} from "ag-grid-enterprise";
import { getData } from "./data";
import { FakeServer } from "./fakeServer";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  RowAutoHeightModule,
  RowGroupingModule,
  ServerSideRowModelModule,
]);

const columnDefs: ColDef[] = [
  {
    headerName: "Group",
    field: "name",
    rowGroup: true,
    hide: true,
  },
  {
    field: "autoA",
    wrapText: true,
    autoHeight: true,
    aggFunc: "last",
  },
  {
    field: "autoB",
    wrapText: true,
    autoHeight: true,
    aggFunc: "last",
  },
];

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: columnDefs,
  defaultColDef: {
    flex: 1,
  },
  autoGroupColumnDef: {
    flex: 1,
    maxWidth: 200,
  },
  // use the server-side row model
  rowModelType: "serverSide",

  suppressAggFuncInHeader: true,

  onGridReady: (params) => {
    // generate data for example
    const data = getData();

    // setup the fake server with entire dataset
    const fakeServer = new FakeServer(data);

    // create datasource with a reference to the fake server
    const datasource = getServerSideDatasource(fakeServer);

    // register the datasource with the grid
    params.api.setGridOption("serverSideDatasource", datasource);
  },
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

function getServerSideDatasource(server: any): IServerSideDatasource {
  return {
    getRows: (params) => {
      console.log("[Datasource] - rows requested by grid: ", params.request);

      const response = server.getData(params.request);

      // adding delay to simulate real server call
      setTimeout(() => {
        if (response.success) {
          // call the success callback
          params.success({
            rowData: response.rows,
            rowCount: response.lastRow,
          });
        } else {
          // inform the grid request failed
          params.fail();
        }
      }, 200);
    },
  };
}
```

[Live example: Auto Row Height Example](https://www.ag-grid.com/examples/server-side-model-row-height/auto-row-height/typescript/)

> **Note**
>
> Ensure `maxBlocksInCache` is not set when using auto row height.

## Changing Row Height

To dynamically set or restore row heights in the Server-Side Row Model, use `setRowHeight()` to apply custom heights to specific rows and `resetRowHeights()` to revert all rows to the values calculated by the `getRowHeight()` in Grid Options. See [Changing Row Height](https://www.ag-grid.com/javascript-data-grid/row-height/#rownodesetrowheightheight-and-apionrowheightchanged) for more.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `resetRowHeights` | `Function` |  |  | Tells the grid to recalculate the row heights. Modules (any of): [`ClientSideRowModelApiModule`](https://www.ag-grid.com/javascript-data-grid/modules/), [`ServerSideRowModelApiModule`](https://www.ag-grid.com/javascript-data-grid/modules/). |

The following example demonstrates this functionality:

- Clicking on a row sets its height to `100px` using `setRowHeight()`.
- Clicking the "Reset Row Heights" button resets all rows to their original heights using `resetRowHeights()`.

#### Reset Row Height Example

```ts
import { GridApi, GridOptions } from "ag-grid-community";
import {
  ModuleRegistry,
  ServerSideRowModelApiModule,
  ServerSideRowModelModule,
  createGrid,
  enableDevValidations,
} from "ag-grid-enterprise";
import { IOlympicDataWithId } from "./interfaces";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ServerSideRowModelModule,
  ServerSideRowModelApiModule,
]);

let gridApi: GridApi<IOlympicDataWithId>;

const gridOptions: GridOptions<IOlympicDataWithId> = {
  columnDefs: [
    { field: "athlete", minWidth: 200 },
    { field: "age" },
    { field: "country", minWidth: 180 },
    { field: "year" },
    { field: "date", minWidth: 150 },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
    { field: "total" },
  ],
  defaultColDef: {
    flex: 1,
    minWidth: 100,
    // allow every column to be aggregated
    enableValue: true,
    sortable: false,
  },
  getRowId: (p) => String(p.data?.id),
  getRowHeight: (p) => {
    return 50 + 30 * Math.sin((p.data?.id ?? 0) / 5 - Math.PI / 2);
  },
  autoGroupColumnDef: {
    minWidth: 200,
  },
  onRowClicked: (p) => {
    p.node.setRowHeight(100);
    p.api.onRowHeightChanged();
  },
  // use the server-side row model
  rowModelType: "serverSide",
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;

function resetRowHeights() {
  gridApi.resetRowHeights();
}

gridApi = createGrid(gridDiv, gridOptions);

function createServerSideDatasource(server) {
  return {
    getRows: (params) => {
      console.log("[Datasource] - rows requested by grid: ", params.request);

      // get data for request from our fake server
      const response = server.getData(params.request);

      // simulating real server call with a 500ms delay
      setTimeout(() => {
        if (response.success) {
          // supply rows for requested block to grid
          params.success({
            rowData: response.rows,
            rowCount: response.lastRow,
          });
        } else {
          params.fail();
        }
      }, 500);
    },
  };
}

function createFakeServer(allData) {
  return {
    getData: (request) => {
      // take a slice of the total rows for requested block
      const rowsForBlock = allData.slice(request.startRow, request.endRow);

      // here we are pretending we don't know the last row until we reach it!
      const lastRow = getLastRowIndex(request, rowsForBlock);

      return {
        success: true,
        rows: rowsForBlock,
        lastRow: lastRow,
      };
    },
  };
}

function getLastRowIndex(request, results) {
  if (!results) return undefined;
  const currentLastRow = (request.startRow || 0) + results.length;

  // if on or after the last block, work out the last row, otherwise return 'undefined'
  return currentLastRow < (request.endRow || 0) ? currentLastRow : undefined;
}

fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then(function (data) {
    // adding row id to data
    let idSequence = 0;
    data.forEach(function (item: { id: number }) {
      item.id = idSequence++;
    });

    // setup the fake server with entire dataset
    const fakeServer = createFakeServer(data);

    // create datasource with a reference to the fake server
    const datasource = createServerSideDatasource(fakeServer);

    // register the datasource with the grid
    gridApi.setGridOption("serverSideDatasource", datasource);
  });

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).resetRowHeights = resetRowHeights;
}
```

[Live example: Reset Row Height Example](https://www.ag-grid.com/examples/server-side-model-row-height/resetting-row-height/typescript/)
