This section covers some common lifecycle events that are raised after grid initialisation, data updates, and before the grid is destroyed.
The events on this page are listed in the order they are raised.
Grid Ready Copy Link
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.
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;
}
.test-grid {
flex-grow: 1;
}
.test-container {
height: 100%;
display: flex;
flex-direction: column;
}
.test-header {
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 13px;
margin-bottom: 1rem;
display: flex;
gap: 1em;
align-items: baseline;
}
export interface TAthlete {
name: string;
medals: {
gold: number;
silver: number;
bronze: number;
};
person: {
age: number;
country: string;
};
}
export function getData(): TAthlete[] {
return [
{
name: 'Michael Phelps',
person: {
age: 23,
country: 'United States',
},
medals: {
gold: 8,
silver: 0,
bronze: 0,
},
},
{
name: 'Michael Phelps',
person: {
age: 19,
country: 'United States',
},
medals: {
gold: 6,
silver: 0,
bronze: 2,
},
},
{
name: 'Michael Phelps',
person: {
age: 27,
country: 'United States',
},
medals: {
gold: 4,
silver: 2,
bronze: 0,
},
},
{
name: 'Natalie Coughlin',
person: {
age: 25,
country: 'United States',
},
medals: {
gold: 1,
silver: 2,
bronze: 3,
},
},
{
name: 'Aleksey Nemov',
person: {
age: 24,
country: 'Russia',
},
medals: {
gold: 2,
silver: 1,
bronze: 3,
},
},
{
name: 'Alicia Coutts',
person: {
age: 24,
country: 'Australia',
},
medals: {
gold: 1,
silver: 3,
bronze: 1,
},
},
{
name: 'Missy Franklin',
person: {
age: 17,
country: 'United States',
},
medals: {
gold: 4,
silver: 0,
bronze: 1,
},
},
{
name: 'Ryan Lochte',
person: {
age: 27,
country: 'United States',
},
medals: {
gold: 2,
silver: 2,
bronze: 1,
},
},
{
name: 'Allison Schmitt',
person: {
age: 22,
country: 'United States',
},
medals: {
gold: 3,
silver: 1,
bronze: 1,
},
},
{
name: 'Natalie Coughlin',
person: {
age: 21,
country: 'United States',
},
medals: {
gold: 2,
silver: 2,
bronze: 1,
},
},
{
name: 'Ian Thorpe',
person: {
age: 17,
country: 'Australia',
},
medals: {
gold: 3,
silver: 2,
bronze: 0,
},
},
{
name: 'Dara Torres',
person: {
age: 33,
country: 'United States',
},
medals: {
gold: 2,
silver: 0,
bronze: 3,
},
},
{
name: 'Cindy Klassen',
person: {
age: 26,
country: 'Canada',
},
medals: {
gold: 1,
silver: 2,
bronze: 2,
},
},
{
name: 'Nastia Liukin',
person: {
age: 18,
country: 'United States',
},
medals: {
gold: 1,
silver: 3,
bronze: 1,
},
},
{
name: 'Marit Bjørgen',
person: {
age: 29,
country: 'Norway',
},
medals: {
gold: 3,
silver: 1,
bronze: 1,
},
},
{
name: 'Sun Yang',
person: {
age: 20,
country: 'China',
},
medals: {
gold: 2,
silver: 1,
bronze: 1,
},
},
{
name: 'Kirsty Coventry',
person: {
age: 24,
country: 'Zimbabwe',
},
medals: {
gold: 1,
silver: 3,
bronze: 0,
},
},
{
name: 'Libby Lenton-Trickett',
person: {
age: 23,
country: 'Australia',
},
medals: {
gold: 2,
silver: 1,
bronze: 1,
},
},
{
name: 'Ryan Lochte',
person: {
age: 24,
country: 'United States',
},
medals: {
gold: 2,
silver: 0,
bronze: 2,
},
},
{
name: 'Inge de Bruijn',
person: {
age: 30,
country: 'Netherlands',
},
medals: {
gold: 1,
silver: 1,
bronze: 2,
},
},
];
}
<div class="test-container">
<div class="test-header">
<div>
<input type="checkbox" id="pinFirstColumnOnLoad" />
<label for="pinFirstColumnOnLoad">Pin first column on load</label>
</div>
<button id="reloadGridButton" onclick="reloadGrid()">Reload Grid</button>
</div>
<div id="myGrid" style="height: 100%"></div>
</div>
First Data Rendered Copy Link
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 Copy Link
The rowDataUpdated event fires every time the grid's data changes, by Updating Row Data or by applying Transaction Updates. In the Server Side Row Model, use the Model Updated Event 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.
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;
}
.test-grid {
flex-grow: 1;
}
.test-container {
height: 100%;
display: flex;
flex-direction: column;
}
.test-header {
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 13px;
}
.test-header button[disabled] {
opacity: 0.7;
}
.test-header > div {
margin-bottom: 1rem;
}
export interface TAthlete {
name: string;
medals: {
gold: number;
silver: number;
bronze: number;
};
person: {
age: number;
country: string;
};
}
export function fetchDataAsync(): Promise<TAthlete[]> {
// Simulate a slow network request
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ name: 'Michael Phelps', person: { age: 23, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Michael Phelps', person: { age: 19, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Michael Phelps', person: { age: 27, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Natalie Coughlin', person: { age: 25, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Aleksey Nemov', person: { age: 24, country: 'Russia' }, medals: getRandomMedals() },
{ name: 'Alicia Coutts', person: { age: 24, country: 'Australia' }, medals: getRandomMedals() },
{ name: 'Missy Franklin', person: { age: 17, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Ryan Lochte', person: { age: 27, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Allison Schmitt', person: { age: 22, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Natalie Coughlin', person: { age: 21, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Ian Thorpe', person: { age: 17, country: 'Australia' }, medals: getRandomMedals() },
{ name: 'Dara Torres', person: { age: 33, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Cindy Klassen', person: { age: 26, country: 'Canada' }, medals: getRandomMedals() },
{ name: 'Nastia Liukin', person: { age: 18, country: 'United States' }, medals: getRandomMedals() },
{ name: 'Marit Bjørgen', person: { age: 29, country: 'Norway' }, medals: getRandomMedals() },
{ name: 'Sun Yang', person: { age: 20, country: 'China' }, medals: getRandomMedals() },
]);
}, 600);
});
}
function getRandomMedals() {
return {
gold: Math.floor(window.agRandom() * 10),
silver: Math.floor(window.agRandom() * 10),
bronze: Math.floor(window.agRandom() * 10),
};
}
<div class="test-container">
<div class="test-header">
<div id="firstDataRendered">First Data Rendered: <span class="value">-</span></div>
<div id="rowDataUpdated">Row Data Updated: <span class="value">-</span></div>
<div>
<button id="btnReloadData" onclick="onBtnReloadData()">Reload Data</button>
</div>
</div>
<div id="myGrid" style="height: 100%"></div>
</div>
Grid Pre-Destroyed Copy Link
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 demonstrates how gridPreDestroyed can be used to save and restore grid state.