ForEach Action

This action lets you execute another action for each item in an array. 

The ForEach action takes an 'items' and 'actionId', and adds a $current context variable for the called action, or  'Callee', in order to access the current item. The parameters are as follows:

Parameter Name Description
as An optional alias for $current. Used to name the context so that it can be referenced in nested Callees.
actionId An ID in the current action chain.
items An expression that evaluates to an array.
mode "serial" (default) or "parallel".

The "mode" parameter allows for serial or parallel action. Prior to this parameter, the behavior was "serial"; each "actionId" call was made for an item only when any previous item's "actionId" call finished (meaning, any Promise returned from the last action resolves). Using "parallel" means that each "actionId" call does not wait for the previous call to finish (useful for Rest Action calls, etc).Using either mode, the ForEach action does not finish until all Promises returned from the "actionId" chain resolve (if no Promise is returned, it is considered resolved on return).

The following table describes additional properties injected into the available contexts that the called action ('callee') can reference in its parameter expressions:

Parameter Name Description
$current.data The current array item.
$current.index The current array index.
alias.data An alternate syntax for $current.data, which allows a reference to $current from nested contexts.
alias.index An alternate syntax for $current.index, which allows a reference to $current from nested contexts.

The outcome of the action is either:

  • "success", with an array containing the return value of the last action's results; in other words, an array of the return of the "sub-chain" ("chainlet"?) called for each item in the loop,
  • or "failure" if there is some exception/error.

Note: Except for the return value for the last action, the results of each Action are not accessible outside of the sub-chain; for example, if the sub-chain is "actionA" → "actionB", the result of the ForEach will contain an array of "actionB" return values, and not "actionA"'s.

ForEach "as" Alias

By default, the ForEach Action ID in the declaration will be used for the alias to $current.  

Note that if an action has an "as" alias, then the value will be used as the alias instead. For example, for as="foo", you can also create expressions that reference "foo.data" and "foo.index".

Example 1-21 Example 1

In this example, $current.data and forEachCurrent.data are equivalent.

actions: {
   "forEach": {
     "module": "vb/action/builtin/forEachAction",
        "parameters": {
           "items": "{{ $variables.testArray }}",
           "actionId": "someAction",
           "as": "forEachCurrent",
      },
    },
    "someAction": {
       "module": "someRandomAction",
         "parameters": {
             "outcome": "{{ $current.data.foo }}",
             "payload": {
               "text": "{{ forEachCurrent.data.bar }}",
               "index": "{{ $current.index }}' }"
          }
       }
    }
}

Example 1-22 Example 2

This example demonstrates the use of “as”.

"actions": {
  "forEachOuter": {
    "label: 'the outer-most action, a ForEach',
    "module": "vb/action/builtin/forEachAction",
    "parameters": {
      "items": ["a", "b"],
      "actionId": "forEachInner"
    }
  },
  "forEachInner": {
    "label": "the inner-most action, a ForEach, called by a ForEach",
    "module": "vb/action/builtin/forEachAction",
    "as": "inner",
    "parameters": {
      "items": [1, 2],
      "actionId": "someAction",
    }
  },
  "someAction": {
    "label": "a custom action",
    "module": "countToTwoAction",
    "parameters": {
      "someParam": "{{ forEachOuter.data }}",
      "anotherParam": "{{ inner.data }}"
    }
  }
}