AG Grid provides native Angular support with a standalone component, full TypeScript typing, and Angular-specific optimizations.
Installation
Install the packages
Install AG Grid Angular along with the core library:npm install ag-grid-angular ag-grid-community
For enterprise features:npm install ag-grid-angular ag-grid-community ag-grid-enterprise
Import the component
The AgGridAngular component is standalone and can be imported directly:import { AgGridAngular } from 'ag-grid-angular';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
imports: [AgGridAngular],
template: `...`
})
export class AppComponent {}
Import styles
Add styles to your angular.json or component:"styles": [
"node_modules/ag-grid-community/styles/ag-grid.css",
"node_modules/ag-grid-community/styles/ag-theme-quartz.css"
]
Basic Usage
Standalone Component
NgModule
import { Component } from '@angular/core';
import { AgGridAngular } from 'ag-grid-angular';
import { ColDef } from 'ag-grid-community';
interface IRow {
make: string;
model: string;
price: number;
}
@Component({
selector: 'app-root',
standalone: true,
imports: [AgGridAngular],
template: `
<ag-grid-angular
class="ag-theme-quartz"
style="height: 500px"
[rowData]="rowData"
[columnDefs]="columnDefs"
/>
`
})
export class AppComponent {
rowData: IRow[] = [
{ make: 'Tesla', model: 'Model Y', price: 64950 },
{ make: 'Ford', model: 'F-Series', price: 33850 },
{ make: 'Toyota', model: 'Corolla', price: 29600 },
];
columnDefs: ColDef<IRow>[] = [
{ field: 'make' },
{ field: 'model' },
{ field: 'price' }
];
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AgGridAngular } from 'ag-grid-angular';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AgGridAngular
],
bootstrap: [AppComponent]
})
export class AppModule {}
// app.component.ts
import { Component } from '@angular/core';
import { ColDef } from 'ag-grid-community';
@Component({
selector: 'app-root',
template: `
<ag-grid-angular
class="ag-theme-quartz"
style="height: 500px"
[rowData]="rowData"
[columnDefs]="columnDefs"
/>
`
})
export class AppComponent {
rowData = [
{ make: 'Tesla', model: 'Model Y', price: 64950 },
{ make: 'Ford', model: 'F-Series', price: 33850 },
{ make: 'Toyota', model: 'Corolla', price: 29600 },
];
columnDefs: ColDef[] = [
{ field: 'make' },
{ field: 'model' },
{ field: 'price' }
];
}
TypeScript Support
The ag-grid-angular component provides full TypeScript support with strongly-typed interfaces.
import { Component, Input } from '@angular/core';
import { ColDef, GridOptions, Module } from 'ag-grid-community';
@Component({
selector: 'app-grid',
template: `
<ag-grid-angular
[rowData]="rowData"
[columnDefs]="columnDefs"
[gridOptions]="gridOptions"
[modules]="modules"
/>
`
})
export class GridComponent {
@Input() rowData: any[];
@Input() columnDefs: ColDef[];
// Initial grid configuration
gridOptions: GridOptions = {
defaultColDef: {
sortable: true,
filter: true
}
};
// Modules for this grid instance
modules: Module[] = [];
}
Type-Safe Column Definitions
import { ColDef } from 'ag-grid-community';
interface UserData {
id: number;
name: string;
email: string;
age: number;
}
@Component({...})
export class AppComponent {
columnDefs: ColDef<UserData>[] = [
{
field: 'name',
headerName: 'Full Name',
valueGetter: (params) => {
// params.data is typed as UserData
return params.data?.name.toUpperCase();
}
},
{ field: 'email' },
{
field: 'age',
filter: 'agNumberColumnFilter',
cellStyle: (params) => {
// Type-safe access to row data
return params.data.age < 18 ? { color: 'red' } : {};
}
}
];
}
Accessing the Grid API
Access the Grid API through the component’s api property after grid initialization.
ViewChild
onGridReady Event
import { Component, ViewChild } from '@angular/core';
import { AgGridAngular } from 'ag-grid-angular';
@Component({
selector: 'app-root',
template: `
<button (click)="onExportClick()">Export CSV</button>
<button (click)="onSelectAll()">Select All</button>
<ag-grid-angular
#agGrid
class="ag-theme-quartz"
style="height: 500px"
[rowData]="rowData"
[columnDefs]="columnDefs"
[rowSelection]="'multiple'"
/>
`
})
export class AppComponent {
@ViewChild('agGrid') agGrid!: AgGridAngular;
onExportClick() {
this.agGrid.api.exportDataAsCsv();
}
onSelectAll() {
this.agGrid.api.selectAll();
}
}
import { Component } from '@angular/core';
import { GridApi, GridReadyEvent } from 'ag-grid-community';
@Component({
selector: 'app-root',
template: `
<button (click)="onExportClick()">Export CSV</button>
<ag-grid-angular
class="ag-theme-quartz"
style="height: 500px"
[rowData]="rowData"
[columnDefs]="columnDefs"
(gridReady)="onGridReady($event)"
/>
`
})
export class AppComponent {
private gridApi!: GridApi;
onGridReady(params: GridReadyEvent) {
this.gridApi = params.api;
this.gridApi.sizeColumnsToFit();
}
onExportClick() {
this.gridApi?.exportDataAsCsv();
}
}
The Grid API is available after the gridReady event fires.
Event Handling
Bind to grid events using Angular event binding syntax.
import { Component } from '@angular/core';
import {
CellClickedEvent,
RowSelectedEvent,
GridReadyEvent
} from 'ag-grid-community';
@Component({
selector: 'app-root',
template: `
<ag-grid-angular
class="ag-theme-quartz"
style="height: 500px"
[rowData]="rowData"
[columnDefs]="columnDefs"
[rowSelection]="'multiple'"
(cellClicked)="onCellClicked($event)"
(rowSelected)="onRowSelected($event)"
(gridReady)="onGridReady($event)"
/>
`
})
export class AppComponent {
onCellClicked(event: CellClickedEvent) {
console.log('Cell clicked:', event.value);
}
onRowSelected(event: RowSelectedEvent) {
console.log('Row selected:', event.node.data);
}
onGridReady(event: GridReadyEvent) {
console.log('Grid is ready');
event.api.sizeColumnsToFit();
}
}
Custom Angular Components
Use Angular components as cell renderers, editors, and filters.
import { Component } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';
@Component({
selector: 'app-status-renderer',
standalone: true,
template: `
<span [style.color]="color" [style.font-weight]="'bold'">
{{ params.value }}
</span>
`
})
export class StatusRendererComponent implements ICellRendererAngularComp {
params!: ICellRendererParams;
color!: string;
agInit(params: ICellRendererParams): void {
this.params = params;
this.color = params.value === 'active' ? 'green' : 'red';
}
refresh(params: ICellRendererParams): boolean {
return false;
}
}
// Usage in column definitions
columnDefs: ColDef[] = [
{
field: 'status',
cellRenderer: StatusRendererComponent
}
];
Dependency Injection
Inject Angular services into custom grid components.
import { Component, inject } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { HttpClient } from '@angular/common/http';
import { DataService } from './data.service';
@Component({
selector: 'app-custom-renderer',
standalone: true,
template: `<span>{{ displayValue }}</span>`
})
export class CustomRendererComponent implements ICellRendererAngularComp {
// Inject Angular services
private http = inject(HttpClient);
private dataService = inject(DataService);
params!: ICellRendererParams;
displayValue: string = '';
agInit(params: ICellRendererParams): void {
this.params = params;
// Use injected services
this.displayValue = this.dataService.formatValue(params.value);
}
refresh(params: ICellRendererParams): boolean {
return false;
}
}
Change Detection
AG Grid Angular integrates with Angular’s change detection system.
@Component({
selector: 'app-root',
template: `
<button (click)="addRow()">Add Row</button>
<ag-grid-angular
[rowData]="rowData"
[columnDefs]="columnDefs"
/>
`
})
export class AppComponent {
rowData = [...];
addRow() {
// Angular detects the change automatically
this.rowData = [...this.rowData, { make: 'New', model: 'Car' }];
}
}
@Component({
selector: 'app-root',
template: `
<ag-grid-angular
[rowData]="rowData"
[columnDefs]="columnDefs"
[suppressChangeDetection]="true"
/>
`
})
export class AppComponent {
@ViewChild(AgGridAngular) agGrid!: AgGridAngular;
updateData() {
// Manually update grid via API
this.agGrid.api.setGridOption('rowData', newData);
}
}
Use suppressChangeDetection for better performance with large datasets.
The ag-grid-angular component accepts all GridOptions as @Input() properties:
The data to display in grid rows
Column definitions for the grid
Initial grid configuration (component inputs take precedence)
AG Grid modules to register for this instance
Disable automatic Angular change detection for better performance
Enable row selection mode
Output Events Reference
Bind to grid events using Angular’s event binding:
Fired when grid initialization is complete
Fired when a cell is clicked
Fired when a row is selected/deselected
Fired when a cell value is changed after editing
Module Registration
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { ModuleRegistry } from 'ag-grid-community';
import { ClientSideRowModelModule } from 'ag-grid-community';
import { MenuModule } from 'ag-grid-enterprise';
export function registerModules() {
return () => {
ModuleRegistry.registerModules([
ClientSideRowModelModule,
MenuModule
]);
};
}
@NgModule({
providers: [
{
provide: APP_INITIALIZER,
useFactory: registerModules,
multi: true
}
]
})
export class AppModule {}
import { ClientSideRowModelModule } from 'ag-grid-community';
import { MenuModule } from 'ag-grid-enterprise';
@Component({
template: `
<ag-grid-angular
[modules]="modules"
[rowData]="rowData"
[columnDefs]="columnDefs"
/>
`
})
export class GridComponent {
modules = [
ClientSideRowModelModule,
MenuModule
];
}
Server-Side Data
Integrate with Angular’s HttpClient for server-side data.
import { Component, OnInit, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { GridReadyEvent } from 'ag-grid-community';
@Component({
selector: 'app-root',
template: `
<ag-grid-angular
[rowData]="rowData"
[columnDefs]="columnDefs"
[loading]="loading"
(gridReady)="onGridReady($event)"
/>
`
})
export class AppComponent implements OnInit {
private http = inject(HttpClient);
rowData: any[] = [];
loading = true;
columnDefs: ColDef[] = [...];
ngOnInit() {
this.loadData();
}
loadData() {
this.loading = true;
this.http.get<any[]>('/api/data')
.subscribe({
next: (data) => {
this.rowData = data;
this.loading = false;
},
error: (err) => {
console.error('Error loading data', err);
this.loading = false;
}
});
}
onGridReady(params: GridReadyEvent) {
params.api.sizeColumnsToFit();
}
}
Common Patterns
Responsive Grid Height
@Component({
selector: 'app-root',
template: `
<div class="grid-container">
<ag-grid-angular
class="ag-theme-quartz"
[rowData]="rowData"
[columnDefs]="columnDefs"
/>
</div>
`,
styles: [`
.grid-container {
height: calc(100vh - 100px);
}
ag-grid-angular {
height: 100%;
}
`]
})
export class AppComponent {}
Dynamic Column Updates
@Component({
template: `
<label>
<input type="checkbox" [(ngModel)]="showPrice" />
Show Price
</label>
<ag-grid-angular
[columnDefs]="columnDefs"
[rowData]="rowData"
/>
`
})
export class AppComponent {
showPrice = true;
baseColumns: ColDef[] = [
{ field: 'make' },
{ field: 'model' }
];
get columnDefs(): ColDef[] {
return [
...this.baseColumns,
...(this.showPrice ? [{ field: 'price' }] : [])
];
}
}
Troubleshooting
Grid not displaying correctly
Ensure you’ve imported the CSS in your angular.json:"styles": [
"node_modules/ag-grid-community/styles/ag-grid.css",
"node_modules/ag-grid-community/styles/ag-theme-quartz.css"
]
Set explicit height on the grid container:<ag-grid-angular
class="ag-theme-quartz"
style="height: 500px"
/>
Custom components not rendering
Ensure your custom components are:
- Marked as
standalone: true or properly declared
- Implementing the correct interface (e.g.,
ICellRendererAngularComp)
- Have the required lifecycle methods (
agInit, refresh)
Change detection not working
Create new array references when updating data:// Wrong: Mutates existing array
this.rowData.push(newRow);
// Correct: Creates new array reference
this.rowData = [...this.rowData, newRow];
Next Steps
Column Definitions
Configure grid columns
Grid API
Explore API methods
Custom Components
Build Angular components for cells
Styling
Customize appearance