Rendering columns dynamically — AG Grid with React and Typescript
More posts on AG Grid with React and Typescript:
The problem
In our grid, we want have some dynamic columns and not every row of data has all the columns. So in the <Grid />
component, we pass in the custom field schema to specify what fields are on the grid, as well as the data with custom field values.
//Grid.tsxinterface IGridProps {
data: CompanyListMemberRowFragment[];
customFieldDefs: CustomFieldSchema[];
}export const Grid = ({
data,
customFieldDefs,
}: IGridProps) => {
...
<AgGridReact {...} />
}
Custom field schema looks like this:
export type CustomFieldSchema = {
id: string;
name: string;
options: object[];
type: string;
};
Data looks like this:
export type CompanyListMemberRowFragment = {
id:string;
companyName:string;
domain:string;
...
customFields: {
id: string;
name: string;
value: WhateverValue;
type: string;
}[];
};
Problem 1
columnDefs
is dynamic depending on the CustomFieldSchema[]
we pass in.
Problem 2
In data
, customFields
value comes with different types, each needs a different cell renderer.
The solution
For columnDefs
:
{
...,
{
field: ...,
},
...customFieldDefs.map((customFieldDef) => ({
field: customFieldDef.name,
valueGetter: (params) => {
if (!params.data) return undefined;
const field = params.data[customFieldDef.name];
return field && getCustomFieldStringValue(field);
},
cellRenderer: "customFieldCellRenderer",
})),
...
}
Check out full file here.
For rowData
:
rowData = data.map((each) => {
const { id, domain, ..., customFields } = each;
const row = {
id,
domain,
};
customFields?.forEach((customField) => {
row[customField.name] = customField;
});
return row;
});
Full file here.
Custom field cell renderer:
Grid component:
interface IGridProps {
listMembers: CompanyListMemberRowFragment[];
customFields: CustomFieldSchema[];
}export const Grid: React.FC<IGridProps> =
({
listMembers,
customFields,
}) => {
const rows = getCompanyListGridRows(listMembers);
const [columnDefs, setColumnDefs] = useState<any[]>([]);
useEffect(() => {
setColumnDefs(getCompanyListGridColumns(customFields));
}, [customFields]);
return (
<AgGridReact
gridOptions={gridOptions}
columnDefs={columnDefs}
rowData={rows}
/>
);
};
Full file here.
More posts on AG Grid with React and Typescript: