There are several techniques that can be applied to let users pause a flow and resume it. The simplest technique is to enable the Pause button in each of the flow’s screens, and then give the user access to the Paused Flows lightning component, from where they can resume. However, this is not always workable. It doesn’t work, for example, for guest users running the Flow via Community Cloud, and there is often not a good place to put the Paused Flow component where it can be easily found without being in the way.
Another approach is to use Salesforce Surveys, which runs on the Flow engine.
A third way of dealing with this scenario is to add actions to the flow that store and retrieve the values users enter after each screen. If the user loses connectivity, or quits, they can return later and the values they had previously entered will be loaded into the appropriate screen fields.
There are a lot of ways to do this, with varying degrees of complexity, but they share in common a core concept: A custom object that represents an individual flow session. The different values that the user enters are serialized into a single big string that gets stored in a flow session record.
We have a flow called Health Survey. To enable custom resume, we have defined a custom object called Flow_Session__c. This object has two important fields: SessionData, which stores all the values that the user has entered, and SessionToken, which makes it possible for the record to be matched to the user when they return.
In our Health Survey flow, the user is first shown to Screen 1, where they fill in a variety of fields and then click Next. Here we have a design decision: do we want to update the HealthSurveySession record every time the user clicks next? Or do we want the updating to only happen when the user clicks a Save or Pause button? Either way will work. Let’s assume that we’re going to autosave the user’s date each time they click Next.
That means that we’ll need to extract the form data provided by the user in Screen 1, and save it to our HealthSurveySession record.
Storing and Retrieving Answer Data
Take a look at this version of our flow, which supports a single screen of input data:
After each screen, the flow has a Serialize Health Data action that takes all of the fields that the user has been able to edit so far in the flow, serializes their values (serializing means taking an object and converting it into a string) and returning the serialized string. After each step, the Flow Session can be saved with this latest version of the session data.
Before each screen, there’s a Deserialize Health Data action that loads in the string from the current Flow Session (if one exists), and converts it into a HealthSurveySessionData object. This object is then used to map values into the screen. In this way, the values from the previous session get loaded in as defaults when the screen renders:
Where does this useful but focused object come from? It’s defined in Apex as a class and accessed in Flow using Apex-Defined Types.
Here’s what the class looks like:
As you can see, this class doesn’t do anything at all. It’s just a data structure. It’s the Apex equivalent of defining a Custom Object and adding a bunch of Custom Fields.
Let’s go back to our Flow Session. Here’s what one looks like after a user has filled in a screen:
The data that we need to reload into the screen is all there in Session Data. The deserialization process is extremely simple:
Notice how the output of this action is a HealthSurveySessionData object. That’s what gets fed to the inputs of the flow screen. The actual deserialization is carried out with a single line of Apex.
As fields are added to the Flow over time, the HealthSurveySessionData class will need to be updated. However, the two actions will not need modification.
This package installs the classes and demo flow described above.