
In this post we'll go over how to set ag-Grid column definitions dynamically based on the columns in your row data. You will see how to bind and update column definitions in ag-Grid in each major framework. This lets you build a truly dynamic ag-grid that responds to the columns in your dataset rather than a static list of columns set beforehand.
You'll see how specific aspects of column state are preserved during these updates, allowing you to easily update columns without having to implement you own logic to reapply column state.
We demonstrate this in live examples in Angular, React, Vue.JS and JavaScript.
Note: As of ag-Grid version 24, there is no longer a need to set immutableColumns
in your gridOptions
(previously known as deltaColumnMode
) as columns are reactive by default!
Contents
- Column State is maintained when updating columns
- Binding and Updating Column Definitions in Angular
- Binding and Updating Column Definitions in React
- Binding and Updating Column Definitions in Vue.js
- Binding and Updating Column Definitions in Vanilla JavaScript
Column State is maintained when updating columns
Whenever new column definitions are set in ag-Grid, specific aspects of state of the existing columns are automatically preserved. This allows you to easily update column definitions without having to write your own code to save and reapply column state.
Column state is kept for sorting, filtering, column width, pinned columns, column order etc. See the full list of stateful attributes of column definitions and how to save and apply column state in our documentation.
The GIF below shows how adding, removing and even updating columns does not reset column state - we sort the AGE column, resize the COUNTRY column, filter the SPORT column, and all this state is preserved when we add a new ATHLETE column or set header names by clicking the buttons above the grid.

Binding and Updating Column Definitions in Angular
Let's look into how to implement this when using Angular. Please see the live sample below:
Binding column definitions
Binding and updating column definitions in Angular is simple! See the code below and note that the ag-grid-angular
component has its columnDefs
bound to a property in our component of the same name.
<ag-grid-angular
#agGrid
style="width: 100%; height: 300px;"
id="myGrid"
class="ag-theme-alpine"
[columnDefs]="columnDefs"
Any updates to the columnDefs
property in app.component
will be reflected on our ag-Grid instance. For example, see how we set the initial column definitions in the app.component
's constructor function:
constructor(private http: HttpClient) {
//...
this.columnDefs = colDefsAthleteExcluded;
}
Adding/removing columns from column definitions
We can add or remove columns in our ag-Grid instance, simply by updating the columnDefs
bound property, passing in a new set of column definitions.
- Columns that didn't exist previously will be added to the ag-Grid instance.
- Columns that are not included in the new set will be removed from the ag-Grid instance.
Please see the code for this below in the event handlers for the "Include Athlete Column" and "Exclude Athlete Column" buttons:
// removes the athlete column
onBtExcludeAthleteColumn() {
this.columnDefs = colDefsAthleteExcluded;
}
// adds the athlete column
onBtIncludeAthleteColumn() {
this.columnDefs = colDefsAthleteIncluded;
}
Updating existing column definitions
To update existing column definitions, we first call the ag-Grid API method getColumnDefs()
to get a reference to the grid's current columns. We then map over the columns, changing any desired properties before updating our columnDefs
bound property.
ag-Grid will then match existing columns with those in our ag-Grid instance and update the columns that have changed. You can get more details on updating column definitions in our documentation.
Please see the code for this below in the event handlers for the "Set HeaderNames" and "Remove HeaderNames" buttons:
// sets each columns headerName property
setHeaderNames() {
var columnDefs = this.gridApi.getColumnDefs();
columnDefs.forEach(function(colDef, index) {
colDef.headerName = "C" + index;
});
this.columnDefs = columnDefs;
}
// clears each columns headerName property
removeHeaderNames() {
var columnDefs = this.gridApi.getColumnDefs();
columnDefs.forEach(function(colDef, index) {
colDef.headerName = undefined;
});
this.columnDefs = columnDefs;
}
Binding and Updating Column Definitions in React
You can easily implement binding and updating column definitions in React. Please see the live example below:
When using React we have the option of declaring ag-Grid columns declaratively. In the example above you'll see that we're creating ag-Grid Columns by mapping over a state variable columns
and returning a agGridColumn
React component for each column definition, spreading props while doing so:
const App = () => {
const [columns, setColumns] = useState(colDefsAthleteExcluded);
return (
// ...
{columns.map(column => (
<AgGridColumn {...column} key={column.field} />
))}
Adding/removing columns from column definitions
To add or remove columns, we simply have to call the setColumns
setState method, passing in a new set of column definitions.
- Columns that didn't exist previously will be added to the ag-Grid instance.
- Columns that are not included in the new set will be removed from the ag-Grid instance.
Please see the code for this below in the event handlers for the "Include Athlete Column" and "Exclude Athlete Column" buttons:
// removes the athlete column
const onBtExcludeAthleteColumn = () => {
setColumns(colDefsAthleteExcluded);
};
// adds the athlete column
const onBtIncludeAthleteColumn = () => {
setColumns(colDefsAthleteIncluded);
};
Updating existing column definitions
To update existing column definitions, we first call the ag-Grid API method getColumnDefs()
to get a reference to the grid's current columns. We then map over the columns, changing any desired properties before calling setColumns
and updating our columns
state variable.
ag-Grid will then match existing columns with those in our ag-Grid instance and update the columns that have changed. You can get more details on updating column definitions in our documentation.
Please see the code for this below in the event handlers for the "Set HeaderNames" and "Remove HeaderNames" buttons:
// sets each columns headerName property
const setHeaderNames = () => {
const newColumns = gridApi.getColumnDefs();
newColumns.forEach((newColumn, index) => {
newColumn.headerName = "C" + index;
});
setColumns(newColumns);
};
// clears each columns headerName property
const removeHeaderNames = () => {
const newColumns = gridApi.getColumnDefs();
newColumns.forEach((newColumn, index) => {
newColumn.headerName = undefined;
});
setColumns(newColumns);
};
Binding and Updating Column Definitions in Vue.js
You can easily implement binding and updating column definitions in Vue.js. Please see the live example below:
Below you'll see that our ag-grid-vue
component has its columnDefs
bound to a property in our component of the same name.
<ag-grid-vue
style="width: 100%; height: 300px;"
class="ag-theme-alpine"
id="myGrid"
:columnDefs="columnDefs"
Any updates to the columnDefs
property in Vue component will be reflected in our ag-Grid instance. For example, see how we set the initial column definitions in the beforeMount
lifecycle method:
beforeMount() {
// ...
this.columnDefs = colDefsAthleteExcluded;
}
Adding/removing columns from column definitions
To add or remove columns to our ag-Grid instance, we update the columnDefs
bound property, passing in a new set of column definitions.
- Columns that didn't exist previously will be added to the ag-Grid instance.
- Columns that are not included in the new set will be removed from the ag-Grid instance.
Please see the code for this below in the event handlers for the "Include Athlete Column" and "Exclude Athlete Column" buttons:
// removes the athlete column
btnExcludeAthleteColumn() {
this.columnDefs = colDefsAthleteExcluded;
},
// adds the athlete column
btnIncludeAthleteColumn() {
this.columnDefs = colDefsAthleteIncluded;
}
Updating existing column definitions
To update existing column definitions, we first call the ag-Grid API method getColumnDefs()
to get a reference to the grid's current columns. We then map over the columns, changing any desired properties before updating our columnDefs
bound property.
ag-Grid will then match existing columns with those in our ag-Grid instance and update the columns that have changed. You can get more details on updating column definitions in our documentation.
Please see the code for this below in the event handlers for the "Set HeaderNames" and "Remove HeaderNames" buttons:
// sets each columns headerName property
setHeaderNames() {
var columnDefs = this.gridApi.getColumnDefs();
columnDefs.forEach(function(colDef, index) {
colDef.headerName = "C" + index;
});
this.columnDefs = columnDefs;
}
// clears each columns headerName property
removeHeaderNames() {
var columnDefs = this.gridApi.getColumnDefs();
columnDefs.forEach(function(colDef, index) {
colDef.headerName = undefined;
});
this.columnDefs = columnDefs;
}
Binding and Updating Column Definitions in Vanilla JavaScript
You can easily implement binding and updating column definitions in JavaScript. Please see the live example below:
When using vanilla JS, column definitions cannot be bound to a property within our application as JavaScript does not have a built-in mechanism for reactive data. Instead we use the ag-Grid API method setColumnDefs()
to set and update our columns.
Adding/removing columns from column definitions
To add or remove columns to our ag-Grid instance, we call the setColumnDefs
API, passing in a new set of column definitions.
- Columns that didn't exist previously will be added to the ag-Grid instance.
- Columns that are not included in the new set will be removed from the ag-Grid instance.
Please see the code for this below in the event handlers for the "Include Athlete Column" and "Exclude Athlete Column" buttons:
// removes athlete column
function onBtExcludeAthleteColumn() {
gridOptions.api.setColumnDefs(colDefsAthleteExcluded);
}
// adds athlete column
function onBtIncludeAthleteColumn() {
gridOptions.api.setColumnDefs(colDefsAthleteIncluded);
}
Updating existing column definitions
To update existing column definitions, we first call the ag-Grid API method getColumnDefs()
to get a reference to the grid's current columns. We then map over the columns, changing any desired properties before calling setColumnDefs(colDefs)
and passing in the updated columns.
ag-Grid will then match existing columns with those in our ag-Grid instance and update the columns that have changed. You can get more details on updating column definitions in our documentation.
Please see the code for this below in the event handlers for the "Set HeaderNames" and "Remove HeaderNames" buttons:
// sets each columns headerName property
function setHeaderNames() {
var columnDefs = gridOptions.api.getColumnDefs();
columnDefs.forEach(function(colDef, index) {
colDef.headerName = "C" + index;
});
gridOptions.api.setColumnDefs(columnDefs);
}
// clears each columns headerName property
function removeHeaderNames() {
var columnDefs = gridOptions.api.getColumnDefs();
columnDefs.forEach(function(colDef, index) {
colDef.headerName = undefined;
});
gridOptions.api.setColumnDefs(columnDefs);
}
What's next?
We hope that you find this article useful whenever you're looking to bind and update column definitions in ag-Grid. To learn more about updating columns in ag-Grid check out our documentation.
You might also find the following blog posts useful:
- tips for working with headers: Automatic Header Names
- Dynamically creating columns and headers from JSON content
If you would like to try out ag-Grid check out our getting started guides (JS / React / Angular / Vue)
Happy coding!