CxJS

updateTree

import { updateTree } from 'cx/data'; Copied

Recursively updates nodes in a tree structure that match a filter. Returns a new tree with updated nodes, or the original tree if no changes were made.

const updated = updateTree(
  array,
  updateCallback,
  itemFilter,
  childrenField,
  removeFilter,
);
ArgumentTypeDescription
arrayT[]Tree data array to update.
updateCallback(node: T) => TFunction that receives a node and returns the updated node.
itemFilter(node: T) => boolean | nullPredicate returning true for nodes to update. If null, all nodes are updated.
childrenFieldkeyof TName of the property containing child nodes.
removeFilter(node: T) => booleanOptional predicate returning true for nodes to remove.

Returns: A new tree with updates applied, or the original array if unchanged.

Examples

Expand all folders

updateTree(
  data,
  (node) => ({ ...node, $expanded: true }),
  (node) => !node.$leaf,
  "$children",
);

Collapse all folders

updateTree(
  data,
  (node) => ({ ...node, $expanded: false }),
  (node) => !node.$leaf,
  "$children",
);

Rename a node

updateTree(
  data,
  (node) => ({ ...node, name: newName }),
  (node) => node.id === targetId,
  "$children",
);

Add child to a node

updateTree(
  data,
  (node) => ({
    ...node,
    $expanded: true,
    $children: [...(node.$children || []), newChild],
  }),
  (node) => node.id === parentId,
  "$children",
);

Update all nodes

Pass null as the filter to update every node in the tree:

updateTree(data, (node) => ({ ...node, visited: true }), null, "$children");

Update and remove in one pass

Use removeFilter to remove nodes while updating others:

updateTree(
  data,
  (node) => ({ ...node, $expanded: true }),
  (node) => !node.$leaf,
  "$children",
  (node) => node.deleted, // Remove nodes marked as deleted
);

See also: findTreeNode, removeTreeNodes, Tree Operations