Flow and FinishLocation


pulling-hair-out-321x300Have you tried using Flows with Visualforce pages and tried to set the finishLocation to a dynamic value?  Odds are yes, and odds are even better that you had (or are having) no end of frustrations trying to get it to fire right.

The key to get your dynamic finishLocation to fire right is to factor your PageReference in such a way where as you are progressing through the flow and while the wrapper Visualforce page is rerendering, you can effectively capture and utilize Flow output variables.

To start, let’s embed a flow in a Visualforce page:

<apex:page controller="flowController">
<flow:interview name="DemoFlow" interview="{!flDemo}" finishLocation="{!prFinishLocation}" />
</apex:page>

You’ll note that the “interview” attribute is in use.  That is one of the necessary steps to make this work – you need to link your Flow to the controller.

public class flowController{
// Instanciate the Flow for use by the Controller - linked by VF "interview" attribute
 public Flow.Interview.DemoFlow flDemo {get;set;}

 // Factor your PageReference as a full GET/SET
 public PageReference prFinishLocation {
 get {
 PageReference prRef = new PageReference('/your/page/location?var1= + strOutputVariable);
 prRef.setRedirect(true);
 return prRef;
 }
 set { prFinishLocation = value; }
 }

 // Factor your Flow output variable pull as a full GET / SET
 public String strOutputVariable {
 get {
 String strTemp = '';

 if(flDemo != null) {
 strTemp = string.valueOf(flDemo.getVariableValue('your flow output variable name');
 }

 return strTemp;
 }

 set { strOutputVariable = value; }
 } 

}

You’ll see that both the finishLocation’s PageReference as well as the variable that captures the Flow’s output variable are all in fully broken out GET/SET logic.  Factoring your code in this manner is the trick; as you move through the flow, the Visualforce page re-renders each time the user progresses through a Flow Screen.

**NOTE!  There is also a trick to how your actual Flow is set up.  For instance – if your Flow is creating a Contact and you want to direct the user to that Contact’s standard detail record upon completion of the Flow, you will need to have one last screen at the end to force the Visualforce page re-render so your controller can grab that Contact’s Id.

**ANOTHER NOTE!  You will NOT be able to get 100% test coverage when you link Flow to a controller like this.  Because Flow requires user-interaction, if you try and reference the “flDemo” variable from the example above without first checking to see if it’s null (which it will be in the Unit Test), your test will fail.  There is NO way right now (confirmed by Salesforce) to full test a Flow using this method…don’t pull your hair out trying.

Good luck!  Hit me up in the comments if you have other great Flow hacks or if you have issues getting this method to work.

Thanks for reading!

Advertisements

13 thoughts on “Flow and FinishLocation

  1. Hi Andrew:
    I can really relate to your cartoon!!! I’ve been scouring the documentation and developer sites and having no luck. I’m very new to Apex, so please forgive me if my questions are basic. But here goes:
    1) When trying to save the FlowController class I get the following error: Compile Error: unexpected token: ‘{‘ at line 17 column 5
    2) Can I use the finishLocation=”{!URLFOR({!flContactID)}”/> in the PageReference variable?

    Thanks, Michele

    • Hello Michele!

      Aaahhh! That’s what I get for not using an IDE to write that code. Take the “()” off of the end of that line and it’ll work.

      The finishLocation requires a PageReference to work properly – I haven’t tried the URLFOR function, but I would recommend going with the PageReference to be for sure.

      Good luck and thanks for reading!!

      -Andy

  2. Hi Andy:
    Ah yes, amazing what two little () can do 🙂
    So now I’m getting an error on line 21 saying variable does not exist. This is what I put in:
    strTemp = string.valueOf(flDemo.getVariableValue(flowContactID));
    flowContactID is a variable I set in the flow as Input/Output that gets set on a lookup after the user inputs the name.

    I also tried this: strTemp = string.valueOf(flDemo.getVariableValue({!flowContactID}));
    but get an error “expecting a right parentheses, found ‘{‘ at line 21 column 50”

    Thanks for your help.
    -Michele

    • Hi Michele!

      Getting ramped up in APEX can be quite an uphill battle. =)

      What I would suggest from here is for you to post both your APEX controller and VF page to http://pastebin.ca and then tweet me a link to it. When I see everything in one place I can much better help figure out what’s all going on. @andyboettcher is my twitter handle.

      Talk to you soon!

      -Andy

  3. Hi Andrew, Thanks for the Code!

    However I would like to run this for a new trigger ready flow. When I alter my flow to have a finish screen it works with your contoller example. But if I make my flow trigger ready with no screens, it does not work. Get Invalid Page Redirection. I really don’t want to have a finish screen since I am just updating a record and want to redirect to that record.

    Any ideas on how to make this work?

  4. Frustratingly, if you have different finish locations based on something your flow is doing, there’s no way to actually test that to make sure it’s working properly. For example, if you were going to redirect the user to a record created in the flow – unless the record wasn’t created and therefore return the user to the starting page.

    You can’t do it, because you need the output of the Flow which you can’t get in the test.

  5. Hey Andy,

    I’ve been trying to modify your code sample to fit my flow but I can’t even save it to try it out, I’m not quite sure what I’m not doing properly, I keep getting different errors and given how new i am, i don’t have too many ideas on how i’d fix them.

    -Nick

  6. Pingback: Flow Finish Location – You can’t get there from here! | In the Nimbus

  7. Hi Andrew,
    This code is awesome, but I also need to pass current record ID to the flow. Wondering there is solution for it.

    Thanks,
    Kalyan

    • I’m looking for the same! The flow is starting from an opportunity, I need to pass in the current opportunity ID, and then finish location should be the newly created contract record from the flow. I can’t figure it out ;(

  8. I’m failing miserably at trying to set a finishlocation that works on both web and Salesforce1. I simply want users to return to the record from which the flow was initiated. vRecordID is passed through a custom link on the initiating record and into the VF page. Any thoughts would be *greatly* appreciated.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s