---
schema_version: "1"
id: a299b1b05d43019091a56297c98a271a9af098cf26df605872774af7a6bb2a5c
title: "Macro Use Case: Recursive Operations"
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/analytics/bi_dev_guide_wave_templates/guides/reference/bi-templatesdev-rules-macros-sample-recursive.md
canonical_url: https://developer.salesforce.com/docs/analytics/bi-dev-guide-wave-templates/guide/bi-templatesdev-rules-macros-sample-recursive.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 19bc69ae65894606072a07682fd7cce9ef85c01469404aff12c33ff070223f14
products:
  - Analytics Templates Developer Guide
  - analytics
---

# Macro Use Case: Recursive Operations

Here’s an example of a macro that deletes an `sfdcDigest` node. It also deletes the digest node and all other nodes that depend on that node.

This macro deletes the specified node and dynamically queries the JSON document to delete each dependency of those nodes.

Consider the simplified JSON below. To delete 'node3' and its dependencies, the result should delete: node3, node4, node5 (depends on node4), node6 (depends on node5), node7, node8, node9.

## Example

Example JSON

```nolang
{
    "node1": { },
    "node2": {
        "dependsOn": "node1"
    },
    "node3": {
        "dependsOn": "node2"
    },
    "node4": {
        "dependsOn": "node3"
    },
    "node5": {
        "dependsOn": "node4"
    },
    "node6": {
        "dependsOn": "node5"
    },
    "node7": {
        "dependsOn": "node3"
    },
    "node8": {
        "dependsOn": "node3"
    },
    "node9": {
        "dependsOn": "node3"
    }
}
```

## Example

Without Macro

Without using a macro (and associated enhancements), nodes would have to be deleted individually.

```nolang
{
    "actions": [
        {
            "action": "delete",
            "path": "$.node3"
        },
        {
            "action": "delete",
            "path": "$.node4"
        },
       {
            "action": "delete",
            "path": "$.node5"
        },
       {
            "action": "delete",
            "path": "$.node6"
        },
        {
            "action": "delete",
            "path": "$.node7"
        },
        {
            "action": "delete",
            "path": "$.node8"
        },
        {
            "action": "delete",
            "path": "$.node9"
        }
    ]
}

```

This code is rigid and difficult to maintain because rules would need to be modified as node dependencies are added and removed from the JSON payload.

## Example

Macro Source

```nolang
{ 
    "namespace": "macroRecursion",
     "definitions": [ 
        { 
            "name": "deleteNodeAndDependencies",
             "description": "Delete a node and its dependencies.  Returns an array of json paths of all the nodes that were deleted.",
             "parameters": [ 
                "nodeName" 
            ],
             "actions": [ 
                {"action": "eval", "key": "fullNodePath",  "value": "$.${p.nodeName}" },
                 {"action": "eval", "key": "dependencies",  "value": "${macroRecursion:getDependents(p.nodeName)}"},
                 { 
                  "action": "eval",
                   "value": "${array:forEach(Rules.Eval.dependencies, '${macroRecursion:deleteNodeAndDependencies(macroRecursion:deleteSingleNodeByFullJsonPath(var))}')}" 
                },
                  { 
                    "action": "eval",
                     "value": "${macroRecursion:deleteSingleNodeByFullJsonPath(Rules.Eval.fullNodePath)}" 
                } 
            ] 
        },
          { 
            "name": "deleteSingleNodeByFullJsonPath",
             "description": "Deletes a node by full json path.",
             "parameters": [ 
                "fullJsonPath" 
            ],
             "actions": [ 
               {"action": "eval", "key": "pathSegments",
  "value": "${string:match(p.fullJsonPath,'\\\\[\\'(.*?)\\'\\\\]')}"},
                { "action": "delete",  "path": "${p.fullJsonPath}"} 
            ],
             "returns": "${array:last(Rules.Eval.pathSegments)}" 
        },
          { 
            "name": "getDependents",
             "description": "Returns the full json path to search results",
             "parameters": [ 
                "nodeName" 
            ],
             "actions": [ 
               { "action": "eval", "key": "searchString", "value": "$.*[?(@.dependsOn=='${p.nodeName}')]"},
                { "action": "eval", "key": "paths", "value": "${json:searchPaths(Rules.Eval.searchString)}"} 
            ],
             "returns": "${Rules.Eval.paths}" 
        } 
    ] }

```

## Example

Rule Calling the Macro

```nolang
{
    "rules": [
        {
            "name": "Recursively delete node3 and dependencies",
            "actions": [
                {"action": "eval", "value": "${macroRecursion:deleteNodeAndDependencies('node3')}" }
            ]
        }
    ]
}
```
