Understanding AG-Grid's API and Column API in React
AG-Grid stands out as a premier data grid for enterprise-level applications, not just for its robust feature set but also for its extensive programmatic control. While configuring the grid via properties is powerful, true mastery comes from leveraging its APIs. This installment in our AG-Grid React series (#31) will demystify how to effectively use both the Grid API and the Column API within your React applications to create dynamic, interactive, and highly customizable data grids.
By the end of this post, you'll understand how to access these APIs and harness their capabilities to manipulate grid data, columns, and overall behavior on the fly, transforming your static grid into a dynamic powerhouse.
What are the AG-Grid API and Column API?
AG-Grid provides two primary API objects that give you programmatic control over almost every aspect of the grid:
The Grid API (gridApi)
The gridApi provides methods to control the data and the overall state and behavior of the grid. This includes operations like:
- Updating row data
- Selecting rows
- Applying filters and sorts
- Exporting data
- Managing grid state (e.g., resizing columns to fit)
- Interacting with row groups, master-detail, and other high-level features
The Column API (columnApi)
The columnApi is specifically designed for column-related operations. It gives you fine-grained control over individual columns or sets of columns, such as:
- Toggling column visibility
- Pinning columns to the left or right
- Reordering columns programmatically
- Resizing columns
- Accessing column definitions and state
- Working with column groups
Accessing the APIs in Your React Component
To use gridApi and columnApi, you first need to obtain their instances. AG-Grid provides these objects through the onGridReady callback property of the AgGridReact component. It's best practice to store these in your component's state.
import React, { useState, useCallback } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
const MyGridComponent = () => {
const [gridApi, setGridApi] = useState(null);
const [columnApi, setColumnApi] = useState(null);
const [rowData] = useState([
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxster', price: 72000 },
]);
const [columnDefs] = useState([
{ field: 'make' },
{ field: 'model' },
{ field: 'price' },
]);
// Callback to store the API instances once the grid is ready
const onGridReady = useCallback((params) => {
setGridApi(params.api);
setColumnApi(params.columnApi);
// You can also perform initial API calls here, e.g., params.api.sizeColumnsToFit();
}, []);
return (
<div className="ag-theme-alpine" style={{ height: 400, width: 600 }}>
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
onGridReady={onGridReady}
/>
</div>
);
};
export default MyGridComponent;
We use React's useState hook to hold the API instances and useCallback for the onGridReady function to ensure it doesn't re-create unnecessarily, which is a good performance practice.
Common Use Cases for the Grid API
Let's explore some practical examples where the gridApi becomes indispensable for managing your grid's data and overall state.
Updating Row Data Dynamically
One of the most frequent uses of gridApi is to update the data displayed in the grid. While passing new rowData to the AgGridReact prop works, setRowData() offers more control, especially in scenarios where you might be streaming data or need to re-apply grid state after data changes.
const updateGridData = (newData) => {
if (gridApi) {
gridApi.setRowData(newData);
console.log('Grid data updated programmatically!');
}
};
// Example usage:
// <button onClick={() => updateGridData(myNewDataSet)}>Update Data</button>
Auto-Sizing Columns
To ensure all columns fit neatly within the grid's visible area, or to size them to their content, sizeColumnsToFit() and autoSizeAllColumns() are invaluable.
const autoSizeAllColumns = () => {
if (gridApi) {
// This resizes all columns to fit the grid's width
gridApi.sizeColumnsToFit();
console.log('Columns resized to fit!');
}
};
// You can also auto-size based on content (requires `suppressColumnVirtualisation: true` or calling `api.resetRowHeights()` after):
const autoSizeColumnsToContent = (columnIds) => {
if (columnApi) {
columnApi.autoSizeColumns(columnIds);
// If you're auto-sizing based on content that might change row height,
// you might need to reset row heights for the grid to re-evaluate them.
// gridApi.resetRowHeights();
console.log('Columns auto-sized to content!');
}
};
// Example usage:
// <button onClick={autoSizeAllColumns}>Fit Columns to Grid</button>
// <button onClick={() => autoSizeColumnsToContent(['make', 'model'])}>Auto-size Make/Model</button>
Getting Selected Rows
When users select rows, you often need to retrieve that data for further processing. getSelectedRows() makes this straightforward.
const getSelectedGridRows = () => {
if (gridApi) {
const selectedNodes = gridApi.getSelectedNodes();
const selectedData = selectedNodes.map(node => node.data);
console.log('Selected Rows:', selectedData);
}
};
// Example usage:
// <button onClick={getSelectedGridRows}>Get Selected</button>
Exporting Data
AG-Grid provides built-in functionality to export grid data to various formats like CSV or Excel. The exportDataAsCsv() method is a common example.
const exportGridData = () => {
if (gridApi) {
gridApi.exportDataAsCsv({ fileName: 'my-grid-data.csv' });
console.log('Data exported to CSV!');
}
};
// Example usage:
// <button onClick={exportGridData}>Export to CSV</button>
Leveraging the Column API for Column Management
The columnApi provides granular control over individual columns, allowing you to react to user interactions or application logic by modifying column properties.
Toggling Column Visibility
You might want to hide or show columns based on user permissions, preferences, or contextual information.
const toggleColumnVisibility = (colId, isVisible) => {
if (columnApi) {
columnApi.setColumnVisible(colId, isVisible);
console.log(`Column '${colId}' is now ${isVisible ? 'visible' : 'hidden'}.`);
// After changing visibility, you might want to auto-size other columns
gridApi.sizeColumnsToFit();
}
};
// Example usage:
// <button onClick={() => toggleColumnVisibility('price', false)}>Hide Price</button>
// <button onClick={() => toggleColumnVisibility('price', true)}>Show Price</button>
Pinning Columns
Pinning columns allows them to remain visible while the user scrolls horizontally. This is crucial for large datasets with many columns.
const pinColumn = (colId, direction) => { // direction can be 'left', 'right', or null (for unpinning)
if (columnApi) {
columnApi.setColumnPinned(colId, direction);
console.log(`Column '${colId}' pinned to: ${direction || 'none'}`);
}
};
// Example usage:
// <button onClick={() => pinColumn('make', 'left')}>Pin Make Left</button>
// <button onClick={() => pinColumn('make', null)}>Unpin Make</button>
Reordering Columns Programmatically
Sometimes you need to programmatically change the order of columns, perhaps based on a saved user layout or a predefined view.
const moveColumnToFirst = (colId) => {
if (columnApi) {
columnApi.moveColumn(colId, 0); // Move to the first position
console.log(`Column '${colId}' moved to the first position.`);
}
};
// Example usage:
// <button onClick={() => moveColumnToFirst('model')}>Move Model to Front</button>
Accessing Column Definitions
The Column API also allows you to retrieve information about the currently displayed or configured columns.
const logColumnInfo = () => {
if (columnApi) {
const displayedColumns = columnApi.getAllDisplayedColumns();
console.log('Currently displayed column IDs:', displayedColumns.map(col => col.getColId()));
const originalDefs = columnApi.getOriginalColumnDefs();
console.log('Original Column Definitions:', originalDefs);
const columnState = columnApi.getColumnState();
console.log('Current Column State (order, width, visibility, etc.):', columnState);
}
};
// Example usage:
// <button onClick={logColumnInfo}>Log Column Info</button>
Combining APIs: A Practical Scenario
Often, you'll find yourself using both APIs in conjunction to achieve a more complex or coordinated grid update. Consider a scenario where you load new data, but for a specific context, you want to hide a certain column and then ensure the remaining columns are optimally sized.
const loadNewDataAndConfigureGrid = (newData, hideColumnId) => {
if (gridApi && columnApi) {
// 1. Update the grid's data using gridApi
gridApi.setRowData(newData);
console.log('Grid data refreshed.');
// 2. Hide a specific column using columnApi
columnApi.setColumnVisible(hideColumnId, false);
console.log(`Column '${hideColumnId}' hidden.`);
// 3. Auto-size the remaining visible columns using gridApi
gridApi.sizeColumnsToFit();
console.log('Visible columns auto-sized to fit.');
}
};
// Example usage (assuming we have some sample new data):
const newCarsData = [
{ make: 'Honda', model: 'Civic', price: 25000, color: 'Red' },
{ make: 'BMW', model: 'X5', price: 60000, color: 'Blue' },
{ make: 'Audi', model: 'A4', price: 45000, color: 'Black' },
];
// Add 'color' to columnDefs if not already there
// const [columnDefs] = useState([
// { field: 'make' },
// { field: 'model' },
// { field: 'price' },
// { field: 'color' } // Make sure this exists in your columnDefs
// ]);
// <button onClick={() => loadNewDataAndConfigureGrid(newCarsData, 'color')}>
// Load New Data & Hide Color
// </button>
This example clearly demonstrates the synergy between gridApi for data management and columnApi for column presentation, resulting in a cohesive user experience.
Best Practices for Using AG-Grid APIs in React
- State Management: Always store
gridApiandcolumnApiin React state (e.g., viauseState) to ensure your component can reliably access them. - Null Checks: The API instances are only available after
onGridReadyis fired. Always include null or undefined checks (if (gridApi) { ... }) before calling any API methods to prevent errors. useCallbackforonGridReady: Wrap youronGridReadyfunction withuseCallbackto prevent it from being recreated on every render, which can lead to unnecessary grid re-initializations or performance issues.- Performance Considerations: While powerful, frequent or complex API calls can impact performance. Be mindful of batching updates where possible, especially for operations that trigger layout recalculations or re-renders.
- Immutability and React State: When interacting with methods like
setRowData, ensure the data you pass respects React's immutability principles if you're also managing that data in your component's state.
Conclusion
Mastering the Grid API and Column API is fundamental to unlocking the full potential of AG-Grid in your React applications. These powerful interfaces provide the tools you need to build dynamic, responsive, and highly interactive data grids that adapt to complex business logic and user demands.
By understanding how to access and effectively utilize methods like setRowData, sizeColumnsToFit, setColumnVisible, and moveColumn, you can create a truly superior user experience. Continue exploring the extensive AG-Grid documentation for a complete list of API methods and their advanced configurations, empowering you to tackle even the most intricate grid challenges.