Rendering columns dynamically — AG Grid with React and Typescript

May Chen
NEXL Engineering
Published in
2 min readDec 3, 2021
AG Grid with dynamic columns

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.

--

--

May Chen
NEXL Engineering

A developer who occasionally has existential crisis and thinks if we are heading to the wrong direction, technology is just getting us there sooner.