How To

View the Uploaded File List After Uploading the Files via Screen Flow

UploadFiles

Those flownatics who have used the OOTB file upload component know once the files are uploaded to the screen flow, that the files are not shown back to the user as a confirmation of the files uploaded. This can be achieved using OOTB flow by querying the documents, assigning the file title and extension to a text template adding it to a variable and then displaying that variable on a flow screen.

Here are a few lessons learned from implementing this use case:

  • Learn part of the data model for Salesforce Files
  • Learn how to query the objects to retrieve the file’s filename and extension for use in flow

Business Use Case:  Addison Dogster is the system administrator at Universal Containers. Samantha Smith is the Operations manager. She would like give her team the ability to quickly create a new contact and associate files to the contact and review the files that were uploaded.

NewContactAndAssociatedFilesDemoView image full screen

Solution: Addison had to first understand how Files were stored in Salesforce. Then, she was able to determine that she is able to get this information in flow to show back to the users post upload.

Let’s take a look at the data schema for Files.

They are stored in several related objects but the two we will focus on are ContentDocumentLink and Content Document.

ContentDocumentLink represents the link between a Salesforce CRM Content document or Salesforce file and where it’s shared. You can view more information on this object in the SOAP API Developer Guide.

For our purpose, we are interested in two fields: LinkedEntityId (the ID of the linked object) and ContentDocumentId (the document Id).

ContentDocument represents a document that has been uploaded to a library in Salesforce CRM Content or Salesforce Files. You can view more information on this object in the SOAP API Developer Guide.

For our purpose, we are interested in two fields: Title (the title of the document) and File Extension (File extension of the document).

The automation solution (screen flow) looks like this:

CreateaNewContactandAssociatedFiles

View image full screen

This flow will: (1) show a screen for the user to provide the contact first and last name, (2) creates the contact, (3) show a screen with the file upload component, (4) query content document link object for the ContentDocumentIds associated to the contact, (5) take each ContentDocumentId through a loop, (6) get the ContentDocument information*, (7) assign a text template to a variable and (8) show the contact and file information on a screen with the ability to upload additional files or access the record link directly.

*Note: Yes, having DML actions within a loop is frowned upon. However in this use case, we only expect to get a handful of files to associate to the contact so the likelihood that we will hit a DML limit is slim.

Highlighted Steps: 

1. Create the screen flow shown above. In Lightning Experience, it is found under Process Automation | Flows. Click on “New Flow.” Select Screen Flow. Click on the Create button.

In the flow, we would configure the following flow resources.

A. We need to create a variable resource to store the newly created contactId to relate the files to.

Best practice tip: Provide a description so you and other/future admins know what this flow resource is used for.

This is how that flow resource would be configured.

  • Resource Type: Variable
  • API Name: varContactId
  • Data Type: Type

varContactIdView image full screen

B. We need to create a text template to store the contentdocumentid’s file name and extension.

Best practice tip: Provide a description so you and other/future admins know what this flow resource is used for.

This is how that flow resource would be configured.

  • Resource Type: Text Template
  • API Name: TextTemplateFileInfo
  • Body: {!Get_ContentDocumentId_Info.Title}.{!Get_ContentDocumentId_Info.FileExtension}

View image full screen

C. For our last flow resource, we will configure a variable to store text template for each contentDocumentId.

Best practice tip: Provide a description so you and other/future admins know what this flow resource is used for.

This is how that flow resource would be configured.

  • Resource Type: Variable
  • API Name: varFileTitleResultsRow
  • Data Type: Text

varFileTitleResultsRowView image full screen

D. First, we configure a Screen flow element to collect the first and last name of the contact to be created

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure as follows:

  • Add a Display Text component:
    • API Name: ContactText
    • Text: Create a new contact below.
  • Add a Name component:
    • API Name: ContactName
    • Fields to Display: firstName, lastName
  • Screen Properties:
    • Configure Frame: deselect Header
    • Control Navigation: deselect Pause and Previous

CreateaNewContactandAssociatedFiles-Screen1View image full screen

E. We need to create a formula resource to determine the number of licenses available by taking the number of used licenses away from the total number of licenses.

Best practice tip: Provide a description so you and other/future admins know what this flow resource is used for.

This is how that flow resource would be configured.

View image full screen

F. Configure a Create Records flow element to create the new contact using the first and last name from the screen flow. We also want to store the newly created contact Id for use later in the flow.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure as follows:

  • How Many Records to Create: One
  • How to Set the Record Fields: Use separate resources and literal values
  • Object: Contact
  • Set Field Values for the Contact:
    • FirstName: {!ContactName.firstName}
    • LastName: {!ContactName.lastName}
  • Store Contact ID in Variable: {!varContactId}

CreateaNewContactandAssociatedFiles-CreateRecordsView image full screen

G. Next, create a Screen flow element called Out of Licenses. This shows instructional text that informs the user that the org is out of licenses.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure to match the below:

  • Control Navigation: Deselect Previous and Pause
  • Add a Display Text component:
    • API Name: FileUploadText
    • Text: Upload any associated files for the contact and click Next. If you do not have files to upload just click Next.
  • Add a File Upload component:
    • API Name: FileUploadComponent
    • File Upload Label: {!$GlobalConstant.EmptyString}
    • Allow Multiple Files: {!$GlobalConstant.True}
    • Related Record ID: {!varContactId} [This associates the files to the newly created Contact]

CreateaNewContactandAssociatedFiles-Screen2View image full screen

H.  We need a Get Records flow element called Get Files to get information for the files or contentDocumentIds that are related to the contact.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure to match the below:

  • Object: Content Document Link
  • Condition Requirements: All Conditions Are Met (AND)
    • LinkedEntityId Equals {!varContactId}
  • How Many Records to Store: All Records
  • How to Store Record Data: Automatically store all fields

CreateaNewContactandAssociatedFiles-GetRecordsView image full screen

I. Now, we will bring all the items from our query from Step H ({!Get_Files}) into a loop. So, we need a Loop flow element.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure to match the below:

  • Collection Variable: {!Get_Files}

CreateaNewContactandAssociatedFiles-LoopView image full screen

J. For our next flow element, we need another Get Records, called Get ContentDocumentId Info.  Here, we will get the file name (aka title) and file extension for each contentDocumentId for display purposes later on.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure to match the below:

  • Object: Content Document
  • Filter User Records: All Conditions Are Met (AND)
    • Id Equals {!Loop.ContentDocumentId}
    • How Many Records to Store: Only the first record
    • How to Store Record Data: Automatically store all field

CreateaNewContactandAssociatedFiles-GetRecords2View image full screen

K. We need an Assignment flow element called Add File Title and Extension. What we will do here is add a text template that uses the contentDocumentId’s title and extension and adds it to the variable varFileTitleResultsRow for display in the final screen flow element. Note: this does read backwards. Essentially, you are adding {!TextTemplateFileInfo} to this variable: {!varFileTitleResultsRow}. You do not want to use the Equals operator here as you want to incrementally add values to the variable versus overriding it.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure as follows:

  • Variable: {!varFileTitleResultsRow} Add {!TextTemplateFileInfo}

CreateaNewContactandAssociatedFiles-AssignmentView image full screen

L. Next, we will create our last Screen flow element called Display Files.

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Configure as follows:

  • Add a Display Text component:
    • API Name: FinalScreenText
    • Text:Here is the information you created:First Name: {!ContactName.firstName}

      Last Name: {!ContactName.lastName}

  • Add a Display Text component:
    • API Name: FileText
    • Text:

Uploaded Files: {!varFileTitleResultsRow}

    • Component Visibility: {!varFileTitleResultsRow} Is Null {!$GlobalConstant.False} [This display text component will only show if the variable varFileTitleResultsRow has a value.
  • Add a Display Text Component”
    • API Name: LinkText
    • Text: Access the record (Note: make the word record a hyperlink. The URL link is: /{!varContactId}. This will take the user to the contact record page.)

CreateaNewContactandAssociatedFiles-Screen3View image full screen

M. Now, we need to connect the flow elements to match the screenshot below.

CreateaNewContactandAssociatedFiles-ConnectorsView image full screen

N. Debug the flow to ensure it is working as expected.

O. Save your flow. Let’s call it Create a New Contact and Associated Files.

Best practice tip: Provide a description so you and other/future admins know what this flow is for.

CreateaNewContactandAssociatedFiles-Properties

P. Activate the flow.

Q. You will need to add the flow where you want it to appear.

Now, before you deploy the changes to Production, don’t forget to test the rest of your configuration changes.

  1. Access the screen flow and provide a first and last name.
  2. Upload files.
  3. Confirm the screen shows the contact’s name and uploaded file names with a link to the record or the ability to click on Previous to upload more files.
  4. Click on the Previous button and upload a new file.
  5. Confirm the screen shows the the contact’s name and uploaded file names (including the new one uploaded in the previous step) with a link to the record or the ability to click on Previous to upload more files.
  6. Click on the record link and confirm it takes you to the newly created contact record.

Deployment Notes/Tips:

  • Flow can be deployed to Production in a change set (or can be deployed using a tool such as Metazoa’s Snapshot).
  • You will find the flow in a change set under the Flow Definition component type.
  • Activate the flow post deployment as flows deploy inactive in Production, unless you have opted in on the Process Automation Settings screen, to “Deploy processes and flows as active.” NOTE: With this change, in order to successfully deploy a process or flow, your org’s Apex tests must cover at least 75% of the total number of active processes and active autolaunched flows in your org or you can select 0%, which will run the apex classes not related to your flow.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s