DataGrid data operations
Data Operations
Coordinate sorting, filtering, and paging with one DataGrid state object.
Use local operations when the full array is already in the browser. Use manual operations when the server owns the data and the app needs a single event to request the next processed result.
Local data operations
The grid receives the full dataset through [data]. Sorting, filtering, and paging are processed internally, and (dataStateChange) reports the current combined state for analytics, URL sync, or state persistence.
Loading interactive DataGrid example…
Current local state
{
"page": 1,
"pageIndex": 0,
"skip": 0,
"pageSize": 5,
"sort": [],
"filter": {
"logic": "and",
"filters": []
},
"globalFilter": ""
}Aggregate results
Aggregates use the same operation helper as the grid. They are calculated after filtering and sorting, but before paging, so totals represent the full current result set instead of only the visible page.
Local code snippet
@Component({
imports: [Datagrid],
template: `
<ngb-datagrid
[columns]="columns"
[data]="orders"
[enableSorting]="true"
[filterable]="'row'"
[dataOperations]="true"
[pageable]="{ pageSizes: [5, 10], info: true }"
[pageSize]="5"
(dataStateChange)="state = $event"
/>
`,
})
export class LocalOperationsDemo {
state: NgbDataGridState | null = null;
get result() {
return ngbApplyDataGridOperations(this.orders, {
columns: this.columns,
state: this.state,
aggregates: [
{ field: 'total', aggregate: 'sum' },
{ field: 'total', aggregate: 'average' },
{ field: 'id', aggregate: 'count' },
],
});
}
}
Manual/server-side data operations
The app handles (dataStateChange), sends that state to an API, then passes the returned page through [data] and the full result count through [total]. This lab uses an in-memory mock API to keep the example deterministic.
Loading interactive DataGrid example…
Current manual state
{
"page": 1,
"pageIndex": 0,
"skip": 0,
"pageSize": 5,
"sort": [],
"filter": {
"logic": "and",
"filters": []
},
"globalFilter": ""
}Manual code snippet
@Component({
imports: [Datagrid],
template: `
<ngb-datagrid
[columns]="columns"
[data]="rows"
[total]="total"
[loading]="loading"
[state]="state"
[enableSorting]="true"
[filterable]="'row'"
[filterManual]="true"
[pageable]="{ pageSizes: [5, 10], info: true }"
(dataStateChange)="loadPage($event)"
/>
`,
})
export class ManualOperationsDemo {
state: NgbDataGridState = { page: 1, pageSize: 5, sort: [], filter: { logic: 'and', filters: [] } };
rows: Order[] = [];
total = 0;
loading = false;
loadPage(state: NgbDataGridState): void {
this.state = state;
this.loading = true;
this.ordersApi.query(state).subscribe((result) => {
this.rows = result.data;
this.total = result.total;
this.loading = false;
});
}
}
API information
| API | Type | Usage |
|---|---|---|
[state] | NgbDataGridState | null | Optional controlled state for page, page size, skip, sort, filter, and global filter. |
[dataOperations] | boolean | NgbDataGridProcessOptions | Opts local arrays into the reusable helper pipeline for filter, sort, and page processing. |
(dataStateChange) | EventEmitter<NgbDataGridState> | Emits the complete data-operation state after sort, filter, or page changes. |
ngbApplyDataGridOperations | (data, options) => NgbDataGridDataResult | Reusable helper that returns processed rows, total count, and optional aggregate results. |
ngbCalculateDataGridAggregates | (data, descriptors) => NgbDataGridAggregateResults | Reusable helper for count, sum, average, min, and max aggregate values. |
(sortChange) | { active: string | null; direction: 'asc' | 'desc' | '' } | Existing focused sort event, preserved for backward compatibility. |
(filterChange) | NgbCompositeFilterDescriptor | Existing focused filter event, preserved for backward compatibility. |
(pageChange) | { page: number; pageSize: number } | Existing focused page event, preserved for backward compatibility. |
[total] | number | null | Full server-side result count when the grid receives only the current page. |
[filterManual] | boolean | Skips client-side filter processing when the host app/server owns filtering. |
Usage notes and limitations
- Use one state object to keep sorting, filtering, paging, and search in sync.
- Grouping now uses the same unified state shape through
state.group. - Enable local data operations when the browser already has the full dataset.
- Use the standalone operation helper when you need to process data before passing it to the grid.
- Aggregate values are calculated from the current filtered result, not just the visible page.
- For server-backed grids, return the current rows plus the full total record count.
- Use individual sort, filter, and page events when a screen only needs one specific change.