2.9. Calling subflows

A flow may call another flow as a subflow. The flow will wait until the subflow returns, then respond to the subflow outcome.

subflow-state

Use the subflow-state element to call another flow as a subflow:

<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 above example calls the createGuest flow, then waits for it to return. When the flow returns with a guestCreated outcome, the new guest is added to the booking's guest list.

Passing a subflow input

Use the input element to pass input to the subflow:

<subflow-state id="addGuest" subflow="createGuest">
    <input name="booking" />
    <transition to="reviewBooking" />
</subflow-state>
				

Mapping subflow output

Simply refer to a subflow output attribute by its name within a outcome transition:

<transition on="guestCreated" to="reviewBooking">
    <evaluate expression="booking.guests.add(currentEvent.attributes.guest)" />  
</transition>
				

In the above example, guest is the name of an output attribute returned by the guestCreated outcome.

Checkpoint: calling subflows

Now review the sample booking flow calling 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
                          http://www.springframework.org/schema/webflow/spring-webflow-2.0.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 subflow to add a new guest to the guest list.