Free MuleSoft CONNECT Keynote & Expo Pass Available!

Register now+
Nav

For Each Scope

The For Each scope (foreach) splits a payload into elements and processes them one by one through the components that you place in the scope. It is similar to a for-each/for-loop code block in most programming languages.

It can process any collection, including lists and arrays. The collection can be any supported content type, such as application/json, application/java, or application/xml.

  • By default For Each tries to split the payload. If the payload is a simple Java collection, the For Each scope can split it without any configuration.

  • For Each will not modify the current payload.

  • For non-Java collections, such as XML or JSON, you need to use a DateWeave expression to split data. You use the Collection (collection) field for this purpose.

    Here, the Collection field in For Each is set to iterate over an array stored in payload.topics.

    For Each Component

You can also split an array in batches. Potentially, batches produce quicker processing. Each batch is treated as a separate Mule message. For example, if a collection has 200 elements and you set Batch Size (batchSize) to 50, the For Each scope iteratively processes 4 batches of 50 elements, each as a separate Mule message.

Error Handling

If one of the elements in a collection throws an exception, the For Each scope stops processing that collection and invokes the error handler.

Examples

Iterate a JSON Array


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core"
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
        <flow name="foreach-test-casesFlow" doc:id="df0421a0-4ec5-482e-8b44-44effb6d4c9d" >
                <scheduler doc:name="Scheduler" doc:id="b833c81f-2e6f-4520-bd5b-fa692786a395" >
                        <scheduling-strategy >
                                <fixed-frequency />
                        </scheduling-strategy>
                </scheduler>
                <ee:transform doc:name="Transform Message" doc:id="ed8669cc-e5a3-4ca4-8040-9c18cd355442" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
[
        {
                name: 'Mark',
                lastname: 'Panoti'
        },
        {
                name: 'Alyssa',
                lastname: 'Milano'
        }
]
        ]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
                <foreach doc:name="For Each" doc:id="c3fcdac5-c13a-4de6-bf97-dd7619daa2a3" >
                        <logger level="ERROR" doc:name="Logger" doc:id="c62ea746-65bc-425f-bb59-d515b39fb9b8" message="#['Name is $(payload.name) and lastname is $(payload.lastname)']"/>
                </foreach>
        </flow>
</mule>

In this case, the payload contains a JSON array. For Each iterates over the payload because the collection attribute has not been defined. The payload within For Each is each of the users in the JSON array.

Iterate over a Java Map that is Placed in a Variable


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core"
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
        <flow name="map-keys-iterateFlow" doc:id="323f6bfd-baec-47c5-b65e-e890958fb537" >
                <scheduler doc:name="Scheduler" doc:id="d79f9550-5da8-4c3d-abec-3b2f508431e7" >
                        <scheduling-strategy >
                                <fixed-frequency />
                        </scheduling-strategy>
                </scheduler>
                <ee:transform doc:name="Transform Message" doc:id="4ce789e8-eeca-4cf6-928d-97e1cfd00825" >
                        <ee:message >
                        </ee:message>
                        <ee:variables >
                                <ee:set-variable variableName="users" ><![CDATA[%dw 2.0
output application/java
---
{
        mark: 'Panoti',
        alyssa: 'Milano'
}
]]></ee:set-variable>
                        </ee:variables>
                </ee:transform>
                <foreach doc:name="For Each" doc:id="d25efadf-782c-4904-ac06-1ed259749d0e" collection="#[dw::core::Objects::entrySet(vars.users)]">
                        <logger level="ERROR" doc:name="Logger" doc:id="d6d56214-4b79-45c9-964f-6c4db1a34bc4" message="#['Name is $(payload.key.name) and lastname is $(payload.value)']"/>
                </foreach>
        </flow>
</mule>

The example uses the ee:transform to set a variable named users with a Java map that is created with DataWeave. Then it uses a built-in DataWeave function to get the entries of a map as a collection in order to iterate over it.

Split a Collection into Batches


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core"
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
        <flow name="foreach-test-casesFlow" doc:id="df0421a0-4ec5-482e-8b44-44effb6d4c9d" >
                <scheduler doc:name="Scheduler" doc:id="b833c81f-2e6f-4520-bd5b-fa692786a395" >
                        <scheduling-strategy >
                                <fixed-frequency />
                        </scheduling-strategy>
                </scheduler>
                <ee:transform doc:name="Transform Message" doc:id="ed8669cc-e5a3-4ca4-8040-9c18cd355442" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
[
        {
                name: 'Mark',
                lastname: 'Panoti'
        },
        {
                name: 'Alyssa',
                lastname: 'Milano'
        },
        {
                name: 'Kevin',
                lastname: 'Bacon'
        },
        {
                name: 'Fiona',
                lastname: 'Apple'
        }
]
        ]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
                <foreach doc:name="For Each" doc:id="c3fcdac5-c13a-4de6-bf97-dd7619daa2a3" batchSize="2" >
                        <logger level="ERROR" doc:name="Logger" doc:id="c62ea746-65bc-425f-bb59-d515b39fb9b8" message="#['First user name is $(payload[0].name) and lastname is $(payload[0].lastname)']"/>
                        <logger level="ERROR" doc:name="Logger" doc:id="c62ea746-65bc-425f-bb59-d515b39fb9b8" message="#['Second user name is $(payload[1].name) and lastname is $(payload[1].lastname)']"/>
                </foreach>
        </flow>
</mule>

The batchSize attribute creates sub-arrays of two elements. So inside foreach, the payload will have an array of two elements.

Aggregate the Process of Each Element into a Variable


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core"
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
        <flow name="foreach-test-aggregate" doc:id="df0421a0-4ec5-482e-8b44-44effb6d4c9d" >
                <scheduler doc:name="Scheduler" doc:id="b833c81f-2e6f-4520-bd5b-fa692786a395" >
                        <scheduling-strategy >
                                <fixed-frequency />
                        </scheduling-strategy>
                </scheduler>
                <ee:transform doc:name="Transform Message" doc:id="ed8669cc-e5a3-4ca4-8040-9c18cd355442" >
                        <ee:message >
                                <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
[
        {
                name: 'Mark',
                lastname: 'Panoti'
        },
        {
                name: 'Alyssa',
                lastname: 'Milano'
        }
]
        ]]></ee:set-payload>
                        </ee:message>
                </ee:transform>
                <foreach doc:name="For Each" doc:id="c3fcdac5-c13a-4de6-bf97-dd7619daa2a3" >
                        <set-variable variableName="aggregation" value="#[output application/java --- vars.aggregation default '' ++ payload.name[-1 to 0]]" />
                </foreach>
                <logger level="ERROR" message="#[vars.aggregation]"/>
        </flow>
</mule>

Within the For Each, the example creates an aggregation variable that concatenates the name in reverse. Then that variable can be accessed outside the For Each scope.