The forEach command iterates through the contents of the specified Collection, allowing each item in the Collection to be handled individually. For every item, the child commands within forEach are evaluated with that item as a variable in the context. After the child commands have been repeated for each item, the loop ends and forEach concludes.

This command creates a local variable context for every iteration round, to be used by the child commands. This context will be terminated at the end of the iteration round, taking all the variables created by the child commands with it. If you wish these variable values to not disappear as the round finishes, place them into Collections or Maps in the base variable context, or use the set (OLD) command to overwrite values of existing base context variables.      

Child commands

Any command can be a child of forEach. Every child is evaluated repeatedly, once for every item in the iterated Collection.

Attributes

value


Required
Value type
EL-evaluated
Yes
Collection, Map, Data Item
Yes
This attribute defines the container whose contents the command will iterate through. While this container is primarily expected to be a Collection, two other types of values are also accepted.

The three types are handled in the following ways:
  • If the value is a Collection, forEach iterates through the items in it in their proper order.  
  • If the value is a Map, forEach iterates through its entries. The item of every round is therefore a Map entry that allows both the key and the value to accessed. Note that the order in which the entries appear in is, in most cases, not consistent and basically random.
  • If the value is a Data Item, forEach performs just one loop round, with the Data Item being the item of the round.  
var

Required
Value type
EL-evaluated
Yes String
No
The value of this attribute defines the name of the local context variable that holds the current item of the loop.
varStatus

Required
Value type
EL-evaluated
No String
No
Defines the name of the variable that holds a Loop Status value. Loop Status has the properties count, first, last and index. A new value is generated for every iteration of the loop. Note that count and index are not incremented if the iteration is skipped at onBeforeIteration-handler in the loop controller.

Property count is the number of the iteration starting from 1.
Property index is same as count with the difference that it starts from 0.
Property first is a Boolean true during the first round of the loop.
Property last is a Boolean true during the last round of the loop.
logic

Required
Value type
EL-evaluated
No String
Yes
The resolved value of this attribute should be an ID of a Loop controller that will be used during this forEach's evaluation.

Examples

Use forEach to inspect and do things with contents of Collections, such as Salesforce query results.

<forEach value="${contacts}" var="contact">
        <if test="${contact.Account.Id == targetAccountId}">
          <addItem value="${contact.Name}" collection="${contactNames}">

Defining the varStatus attribute allows use of logic based on the loop's progress. This example builds a nicely formatted String listing names of contacts into the "contactsListed" variable.  

<set var="contactsListed" value="${''}">
      <forEach value="${contacts}" var="contact" varStatus="loopStatus">
        <choose>
          <when test="${loopStatus.first}">
            <set var="contactsListed" value="${contact.Name}">
          <when test="${loopStatus.last}">
            <set var="contactsListed" value="${contactsListed} and ${contact.Name}">
          <otherwise>
            <set var="contactsListed" value="${contactsListed}, ${contact.Name}">