Skip to content

Export ​

FlexTreeManager and FlexTree support exporting the tree to Json and List formats.

The following uses the tree below to illustrate how to export a tree.

  • Root
    • A
    • B
    • C

toJson ​

FlexTreeManager, FlexTree, and FlexTreeNode all support the toJson method, which exports the tree to Json format.

ts
toJson(
    options?: FlexTreeExportJsonOptions<Fields, KeyFields>
): FlexTreeExportJsonFormat<Fields, KeyFields>

interface FlexTreeExportJsonOptions<
    Fields extends Record<string, any> = object,
    KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
> {
    childrenField?: string
    level?: number // Limit the level to export
    fields?: (keyof IFlexTreeNode<Fields, KeyFields>)[]
    includeKeyFields?: boolean
    countField?: string // Attach a descendant-count field
}
  • Parameters
Parameter Type Default Description
options FlexTreeExportJsonOptions None Export options
options.childrenField string 'children' Child field name
options.level number None Limit the level to export
options.fields (keyof IFlexTreeNode<Fields, KeyFields>)[] None Fields to export
options.includeKeyFields boolean false Whether to export key fields
options.countField string None Descendant-count field name
  • Return

Returns a JSON object whose child field name defaults to children; it can be customized via the options.childrenField parameter.

ts
type FlexTreeExportJsonFormat<
  Fields extends Record<string, any> = object,
  KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
  TreeNode extends IFlexTreeNode<Fields, KeyFields> = IFlexTreeNode<Fields, KeyFields>,
  NodeId = NonUndefined<KeyFields["id"]>[1],
> = TreeNode & {
  children?: FlexTreeExportJsonFormat<Fields, KeyFields, TreeNode, NodeId>[];
};
  • Example
ts
import type { FlexTreeOptions, IFlexTreeNode } from "flextree";
import { FlexTreeManager, FlexTree, FlexTreeVerifyError } from "flextree";

import SqliteAdapter from "flextree-sqlite-adapter";
const sqliteDriver = new SqliteAdapter();
await sqliteDriver.open();

const tree = new FlexTree("tree", {
  adapter: sqliteDriver,
});
await tree.load();

tree.toJson();

The output is as follows:

json
{
  "id": 1,
  "name": "root",
  "children": [
    {
      "id": 2,
      "name": "A",
      "children": [
        { "id": 3, "name": "A1" },
        { "id": 4, "name": "A2" },
        { "id": 5, "name": "A3" }
      ]
    },
    {
      "id": 6,
      "name": "B",
      "children": [
        { "id": 7, "name": "B1" },
        { "id": 8, "name": "B2" },
        { "id": 9, "name": "B3" }
      ]
    },
    {
      "id": 10,
      "name": "C",
      "children": [
        { "id": 11, "name": "C1" },
        { "id": 12, "name": "C2" },
        { "id": 13, "name": "C3" }
      ]
    }
  ]
}
  • Notes

    • The toJson method exports the tree to Json format; you can limit the exported level via the options.level parameter.
    • The toJson method can be called on FlexTree and FlexTreeNode.
    • You can specify the exported fields via the options.fields parameter.
    • By default the leftValue and rightValue fields are not exported; use options.includeKeyFields to specify whether to export key fields.
    • You can specify the child field name via the options.childrenField parameter.

countField Descendant Count ​

When options.countField is specified, each node gets an extra field holding its descendant count (0 for leaves):

ts
await manager.toJson({ countField: "count" })
// { "id": 1, "name": "root", "count": 12, "children": [
//    { "id": 2, "name": "A", "count": 3, "children": [...] },
//    ...
// ] }
  • The count is computed as (rightValue - leftValue - 1) / 2 and is always the full descendant count — unaffected by level truncation (with level: 2, the root's count still includes deeper descendants)
  • countField has the same standing as id: it is attached even when fields filtering is specified, independent of includeKeyFields
  • Conflicting with an existing node field throws a FlexTreeError
  • With the recycle bin enabled the count uses the visible scope: by default it excludes recycled nodes (consistent with the exported content); with includeRecyclebin: true it is the full physical count

toList ​

FlexTreeManager, FlexTree, and FlexTreeNode all support the toList method, which exports the tree to a list node array with a pid field.

ts
toList(
    options?: FlexTreeExportListOptions<Fields, KeyFields>
): FlexTreeExportListFormat<Fields, KeyFields>
interface FlexTreeExportListOptions<
    Fields extends Record<string, any> = object,
    KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
> {
    pidField?: string
    level?: number // Limit the level to export
    fields?: (keyof IFlexTreeNode<Fields, KeyFields>)[]
    includeKeyFields?: boolean
    countField?: string // Attach a descendant-count field
}
  • Parameters
Parameter Type Default Description
options FlexTreeExportListOptions None Export options
options.pidField string 'pid' Parent field name
options.level number None Limit the level to export
options.fields (keyof IFlexTreeNode<Fields, KeyFields>)[] None Fields to export
options.includeKeyFields boolean false Whether to export key fields
options.countField string None Descendant-count field name
  • Return

Returns a list node array whose parent field name defaults to pid; it can be customized via the options.pidField parameter.

ts
export type FlexTreeExportListFormat<
  Fields extends Record<string, any> = object,
  KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
  TreeNode extends IFlexTreeNode<Fields, KeyFields> = IFlexTreeNode<Fields, KeyFields>,
  NodeId = NonUndefined<KeyFields["id"]>[1],
  OPTIONS extends FlexTreeExportListOptions<Fields, KeyFields> = FlexTreeExportListOptions<
    Fields,
    KeyFields
  >,
> = ((OPTIONS["fields"] extends string[]
  ? Extract<TreeNode, OPTIONS["fields"][number]>
  : TreeNode) & { [P in OPTIONS["pidField"] & string]: NodeId })[];
  • Example
ts
import type { FlexTreeOptions, IFlexTreeNode } from "flextree";
import { FlexTreeManager, FlexTree, FlexTreeVerifyError } from "flextree";
import SqliteAdapter from "flextree-sqlite-adapter";
const sqliteDriver = new SqliteAdapter();
await sqliteDriver.open();

const tree = new FlexTree("tree", {
  adapter: sqliteDriver,
});
await tree.load();

tree.toList();

The output is as follows:

json
[
  { "id": 1, "name": "root", "pid": 0 },
  { "id": 2, "name": "A", "pid": 1 },
  { "id": 3, "name": "A1", "pid": 2 },
  { "id": 4, "name": "A2", "pid": 2 },
  { "id": 5, "name": "A3", "pid": 2 },
  { "id": 6, "name": "B", "pid": 1 },
  { "id": 7, "name": "B1", "pid": 6 },
  { "id": 8, "name": "B2", "pid": 6 },
  { "id": 9, "name": "B3", "pid": 6 },
  { "id": 10, "name": "C", "pid": 1 },
  { "id": 11, "name": "C1", "pid": 10 },
  { "id": 12, "name": "C2", "pid": 10 },
  { "id": 13, "name": "C3", "pid": 10 }
]

Note

Both toList and toJson support a level parameter to limit the exported level. They can be called on FlexTree and FlexTreeNode. The semantics of countField are described in countField Descendant Count above.

getTree ​

FlexTreeManager provides the getTree method, which builds an in-memory FlexTree object based on the current manager, so that you can use the rich API provided by FlexTree (such as getByPath, find, toJson, toList, etc.).

ts
getTree(options?: FlexTreeOptions): FlexTree<Fields, KeyFields>
  • Example
ts
const tree = manager.getTree()
await tree.load()           // FlexTree must be loaded manually before it can be accessed
tree.getByPath('/A/A-1')

Note

FlexTreeManager also provides two async convenience methods, toJson and toList, which automatically build and load the tree via getTree before exporting:

ts
await manager.toJson()
await manager.toList()