11. Calling Sub-flows
A flow may call another flow as a sub-flow. The flow waits until the sub-flow returns and responds to the sub-flow outcome.
11.1. The subflow-state
Element
The subflow-state
element calls another flow as a subflow, as follows:
<subflow-state id="addGuest" subflow="createGuest">
<transition on="guestCreated" to="reviewBooking">
<evaluate expression="booking.guests.add(currentEvent.attributes.guest)" />
</transition>
<transition on="creationCancelled" to="reviewBooking" />
</subflow-state>
The preceding example calls the createGuest
flow and waits for it to return.
When the flow returns with a guestCreated
outcome, the new guest is added to the booking’s guest list.
11.1.1. Passing a Sub-flow Input
The input
element passes input to the subflow, as follows:
<subflow-state id="addGuest" subflow="createGuest">
<input name="booking" />
<transition to="reviewBooking" />
</subflow-state>
11.1.2. Mapping Sub-flow Output
When a subflow completes, its end-state ID is returned to the calling flow as the event to use to continue navigation.
The sub-flow can also create output attributes to which the calling flow can refer within an outcome transition, as follows:
<transition on="guestCreated" to="reviewBooking">
<evaluate expression="booking.guests.add(currentEvent.attributes.guest)" />
</transition>
In the preceding example, guest
is the name of an output attribute returned by the guestCreated
outcome.
11.2. Checkpoint: Calling Sub-flows
You should review the sample booking flow that calls a subflow:
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
https://www.springframework.org/schema/webflow/spring-webflow.xsd">
<input name="hotelId" />
<on-start>
<evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"
result="flowScope.booking" />
</on-start>
<view-state id="enterBookingDetails">
<transition on="submit" to="reviewBooking" />
</view-state>
<view-state id="reviewBooking">
<transition on="addGuest" to="addGuest" />
<transition on="confirm" to="bookingConfirmed" />
<transition on="revise" to="enterBookingDetails" />
<transition on="cancel" to="bookingCancelled" />
</view-state>
<subflow-state id="addGuest" subflow="createGuest">
<transition on="guestCreated" to="reviewBooking">
<evaluate expression="booking.guests.add(currentEvent.attributes.guest)" />
</transition>
<transition on="creationCancelled" to="reviewBooking" />
</subflow-state>
<end-state id="bookingConfirmed" >
<output name="bookingId" value="booking.id" />
</end-state>
<end-state id="bookingCancelled" />
</flow>
The flow now calls a createGuest
sub-flow to add a new guest to the guest list.