---
title: "Grid Lifecycle"
framework: javascript
version: "36.1.0"
---

# Grid Lifecycle

This section covers some common lifecycle events that are raised after grid initialisation, data updates, and before the grid is destroyed.

> **Note**
>
> The events on this page are listed in the order they are raised.

## Grid Ready

The `gridReady` event fires upon grid initialisation but the grid may not be fully rendered.

**Common Uses**

- Customising Grid via API calls.
- Event listener setup.
- Grid-dependent setup code.

In this example, `gridReady` applies user pinning preferences before rendering data.

#### Using Grid Ready Event

```ts
import {
  ClientSideRowModelModule,
  ColumnApiModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TAthlete, getData } from "./data";

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

ModuleRegistry.registerModules([ColumnApiModule, ClientSideRowModelModule]);

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    { field: "name", headerName: "Athlete", width: 250 },
    { field: "person.country", headerName: "Country" },
    { field: "person.age", headerName: "Age" },
    { field: "medals.gold", headerName: "Gold Medals" },
    { field: "medals.silver", headerName: "Silver Medals" },
    { field: "medals.bronze", headerName: "Bronze Medals" },
  ],
  rowData: getData(),
  onGridReady: (params: GridReadyEvent<TAthlete>) => {
    const checkbox = document.querySelector<HTMLInputElement>(
      "#pinFirstColumnOnLoad",
    )!;
    const shouldPinFirstColumn = checkbox && checkbox.checked;
    if (shouldPinFirstColumn) {
      params.api.applyColumnState({
        state: [{ colId: "name", pinned: "left" }],
      });
    }
  },
};

function reloadGrid() {
  if (gridApi) {
    gridApi.destroy();
  }

  setTimeout(() => {
    // Artificial delay to show grid being destroyed and re-created
    const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
    gridApi = createGrid(gridDiv, gridOptions);
  }, 500);
}

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

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

[Live example: Using Grid Ready Event](https://www.ag-grid.com/examples/grid-lifecycle/grid-ready/typescript/)

## First Data Rendered

The `firstDataRendered` event fires the first time data is rendered into the grid. It will only be fired once unlike `rowDataUpdated` which is fired on every data change.

## Row Data Updated

The `rowDataUpdated` event fires every time the grid's data changes, by [Updating Row Data](https://www.ag-grid.com/javascript-data-grid/data-update-row-data/) or by applying [Transaction Updates](https://www.ag-grid.com/javascript-data-grid/data-update-transactions/). In the [Server Side Row Model](https://www.ag-grid.com/javascript-data-grid/server-side-model/), use the [Model Updated Event](https://www.ag-grid.com/javascript-data-grid/grid-events/#reference-gridLifecycle-modelUpdated) instead.

In this example the time at which `firstDataRendered` and `rowDataUpdated` are fired is recorded above the grid. Note that `firstDataRendered` is only set on the initial load of the grid and is not updated when reloading data.

#### Using Row Data Event

```ts
import {
  ClientSideRowModelModule,
  FirstDataRenderedEvent,
  GridApi,
  GridOptions,
  ModuleRegistry,
  RowDataUpdatedEvent,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TAthlete, fetchDataAsync } from "./data";

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

ModuleRegistry.registerModules([ClientSideRowModelModule]);

const updateRowCount = (id: string) => {
  const element = document.querySelector(`#${id} > .value`);
  element!.textContent = `${new Date().toLocaleTimeString()}`;
};

const setBtnReloadDataDisabled = (disabled: boolean) => {
  (document.getElementById("btnReloadData") as HTMLButtonElement).disabled =
    disabled;
};

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    { field: "name", headerName: "Athlete" },
    { field: "person.age", headerName: "Age" },
    { field: "medals.gold", headerName: "Gold Medals" },
  ],
  loading: true,
  onFirstDataRendered: (event: FirstDataRenderedEvent) => {
    updateRowCount("firstDataRendered");
    console.log("First Data Rendered");
  },
  onRowDataUpdated: (event: RowDataUpdatedEvent<TAthlete>) => {
    updateRowCount("rowDataUpdated");
    console.log("Row Data Updated");
  },
  onGridReady: () => {
    console.log("Loading Data ...");
    fetchDataAsync()
      .then((data) => {
        console.log("Data Loaded");
        gridApi!.setGridOption("rowData", data);
      })
      .catch((error) => {
        console.error("Failed to load data", error);
      })
      .finally(() => {
        gridApi!.setGridOption("loading", false);
        setBtnReloadDataDisabled(false);
      });
  },
};

function onBtnReloadData() {
  console.log("Reloading Data ...");
  setBtnReloadDataDisabled(true);
  gridApi!.setGridOption("loading", true);
  fetchDataAsync()
    .then((data) => {
      console.log("Data Reloaded");
      gridApi!.setGridOption("rowData", data);
    })
    .catch((error) => {
      console.error("Failed to reload data", error);
    })
    .finally(() => {
      gridApi!.setGridOption("loading", false);
      setBtnReloadDataDisabled(false);
    });
}

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

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

[Live example: Using Row Data Event](https://www.ag-grid.com/examples/grid-lifecycle/row-data-updated/typescript/)

## Grid Pre-Destroyed

The `gridPreDestroyed` event fires just before the grid is destroyed and is removed from the DOM.

**Common Uses**

- Clean up resources.
- Save grid state.
- Disconnect other libraries.

The [Grid State Example](https://www.ag-grid.com/javascript-data-grid/grid-state/#saving-and-restoring-state) demonstrates how `gridPreDestroyed` can be used to save and restore grid state.
