---
title: "Tree Data - Nested Records"
enterprise: true
framework: javascript
version: "36.1.0"
---

# Tree Data - Nested Records

Configure the grid to display structured data by providing nested records.

## Providing Hierarchy

Each row in the data can contain a field containing an array of child rows. The `treeDataChildrenField` property is used to specify the field containing the child rows.

The below structure demonstrates a simple hierarchy, wherein the `treeDataChildrenField` grid option would specify `"children"` as the field containing child rows:

```
const data = [
    {
        id: 'A',
        children: [
            { id: 'B' },
            { id: 'C' },
        ]
    },
    {
        id: 'D',
        children: [
            {
                id: 'E',
                children: [
                    { id: 'F' },
                ]
            }
        ]
    }
]
```

In the above hierarchy, the 'A' row is the parent of 'B' and 'C'. The 'D' row is the parent of 'E' which is the parent of 'F'.

> **Note**
>
> Due to the nature of the nested records, the grid does not support transactions when using `treeDataChildrenField`.

## Providing Group Values

When providing a nested hierarchy, the grid will use the row ID as the group value by default. To provide a custom value, the field property of the `autoGroupColumnDef` grid option can be used.

The example below demonstrates a case where the `autoGroupColumnDef` field is set to `name` to display a group value:

#### Group Values

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    {
      field: "modified",
    },
    {
      field: "created",
    },
  ],
  defaultColDef: {
    flex: 1,
  },
  autoGroupColumnDef: {
    headerName: "Name",
    field: "name",
    cellRendererParams: {
      suppressCount: true,
    },
  },
  rowData: getData(),
  treeData: true, // enable Tree Data mode
  treeDataChildrenField: "children",
  groupDefaultExpanded: -1, // expand all groups by default
};

// wait for the document to be loaded, otherwise
// AG Grid will not find the div in the document.
// lookup the container we want the Grid to use
const eGridDiv = document.querySelector<HTMLElement>("#myGrid")!;

// create the grid passing in the div to use together with the columns & data we want to use
gridApi = createGrid(eGridDiv, gridOptions);
```

[Live example: Group Values](https://www.ag-grid.com/examples/tree-data-nesting/basic-example/typescript)

The following snippet demonstrates how to provide nested siblings with a custom group value:

```js
const gridOptions = {
    treeData: true,
    treeDataChildrenField: 'children',
    autoGroupColumnDef: {
        field: 'name',
    },

    // other grid options ...
}
```

## Supplied vs Aggregated

When using Tree Data, columns defined with an aggregation function will always perform aggregations on the group nodes. This means any supplied group data will be ignored in favour of the aggregated values.

#### Aggregated Data

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    {
      headerName: "Aggregated (Sum)",
      aggFunc: "sum",
      field: "items",
    },
    {
      headerName: "Provided",
      field: "items",
    },
  ],
  defaultColDef: {
    flex: 1,
  },
  autoGroupColumnDef: {
    headerName: "Name",
    field: "name",
    cellRendererParams: {
      suppressCount: true,
    },
  },
  rowData: getData(),
  treeData: true, // enable Tree Data mode
  treeDataChildrenField: "children",
  groupDefaultExpanded: -1, // expand all groups by default
};

// wait for the document to be loaded, otherwise
// AG Grid will not find the div in the document.
// lookup the container we want the Grid to use
const eGridDiv = document.querySelector<HTMLElement>("#myGrid")!;

// create the grid passing in the div to use together with the columns & data we want to use
gridApi = createGrid(eGridDiv, gridOptions);
```

[Live example: Aggregated Data](https://www.ag-grid.com/examples/tree-data-nesting/aggregated-data/typescript)

The example above uses the configuration below to demonstrate the `Desktop` row is being aggregated to show the sum of its children (4), rather than the provided value (1), despite both columns showing the same field:

```
const gridOptions = {
    treeData: true,
    columnDefs: [
        {
            headerName: 'Aggregated (Sum)',
            aggFunc: 'sum',
            field: 'items',
        },
        {
            headerName: 'Provided',
            field: 'items',
        },
    ],
};
```

Refer to the [Aggregation](https://www.ag-grid.com/javascript-data-grid/aggregation/) page for more details, and [Editing Groups](https://www.ag-grid.com/javascript-data-grid/grouping-edit/) for editing aggregated values with cascading updates to children.
