Salesforce Spring 18 Review

In a little over a month, the Salesforce Spring 18 release will be live. Here’s my review of the noteworthy things. For a complete list, check out Spring 18 Release Notes PDF.


This release feels a bit lighter and contains more polish items than big new features. For example, the release notes are only 400ish pages vs the 500 or so pages from the Winter release notes PDF.

I’m excited to learn more about Surveys, Dynamically Starting Flows from Apex, and the new Lightning:RecordEditForm and Lightning:inputField components.

Other notable items include

  • More Gmail & Outlook synching features
  • Better Lightning Report builder options
  • Even more Lightning Styling and Visibility options

Temporary Tabs & Manage Tabs

Temporary tabs are also a great way to manage items that aren’t in your current app. For example, let’s say you open an item from the App Launcher, from your favorites list, or from a link. If it’s not already accessible from the navigation bar, the item opens as a temporary tab where it’s in easy reach.

Add your own items to the navigation bar and tweak them to suit how you work. • Change the order of items to match your workflow • Rename or remove items that you’ve added

Temporary tabs are interesting. They feel like the baby of recent items and bread crumbs in one. It’s also handy that you can know customize your tabs to make them like you want. This was a nice Classic feature that’s now available in Lightning.

LEX Branding

One can use “Themes” to stylize Lightning Experience for each app. One can brand an image and colors, upload a background image, default banners, and avatars for groups and user profiles. This is the “My Lightning” that was announced at Dreamforce. It’s nice to have this flexibility but I wasn’t blown away by it.

Salesforce Surveys

Introducing Salesforce Surveys! Create beautiful, easy-to-use forms for collecting feedback and data from your users or customers. Add different types of questions to gather the data you need. All your valuable survey data is stored in your org, so you can harness the power of Salesforce to view data, create reports and dashboards, and share insights with your company. This feature is generally available in Classic and Lightning Experience.

This is very interesting. One client in particular can harness this by gathering feedback from their field reps when new customizations are released instead of using a custom solution.

Enable the New URL Format for Lightning Experience and the Salesforce Mobile App (Critical Update)

We’re changing the URL format used by Lightning Experience standard apps and the Salesforce mobile app. The new URL format is more readable and addresses the issue of being directed to an unexpected location when accessing Lightning Experience URLs before authenticating. This update doesn’t apply to console apps and communities.

Current format: https:///one/

New format: https:///lightning/o/Account/home

This is why one should use the Lightning APIs to redirect to other pages because if you don’t, your custom functionality will break without changing it.

Reduce the Noise on Your Console Pages with Collapsible Sections

Organize and present information in sections that collapse and expand by customizing your Lightning console app pages with the Accordion component. Only one section is expanded at a time, so your console users can focus on the information they’re working with. This feature is new in Lightning Experience.

Thank you! Console apps can be very busy.

Share Credit for a Deal in Lightning Experience

Opportunity splits make it easy for sales reps to collaborate on opportunities and share opportunity with team members. This feature is new in Lightning Experience.

Team members working an opportunity can see how much credit they get for each deal. Roll individual sales credits into quota and pipeline reports for the entire team.

This will be very handy for bigger deals that involve multiple sales reps so they can share the credit.

Stay on Top of Duplicate Records by Using Duplicate Jobs

Good clean data builds the trust of your sales team. It also helps you work toward complying with various data protection and privacy regulations. So you’ve got everything to gain by getting a global view of duplicate records. Use duplicate jobs with standard or custom matching rules to scan your Salesforce business or person accounts, contacts, or leads for duplicates. Share job results with others and merge the duplicates—all within Salesforce. Use information about duplicate jobs you’ve run to track your progress in reducing duplicate records. This feature is new in Lightning Experience.

This new addition to “Duplicate Management” is great and makes it much easier to detect and manage duplicate records on demand.

Lightning Report Builder Beta (Take Two)

The second beta release of the Lightning Experience report builder lets you categorize report data with buckets, include or exclude results from related objects with cross filters, and summarize data in new ways with summary formula columns. These changes apply to Lightning Experience only.

From the Report Properties menu, you can rename, change the description, or move your report to another folder. This feature is new in Lightning Experience.

Cross-Object Filters is one of my favorite reporting capabilities and am very glad to see it now available in Lightning.

Include Related Fields and Other Objects in Component Visibility Rules

Previously, you could only define component visibility rules on Lightning record pages based on the fields directly on the record. Now you can create filters that are much more robust.

For example, on record pages, you can select fields from the record by clicking Record Field. Or click Advanced to expand your field selections to related fields, related objects, or fields from other objects such as Client and User.

Having more options for component visibility rules is awesome because it allows even more granular visibility.

Build Richer Flow Screens with Lightning Components

Now that flow screens have Lightning components, the world is your oyster—you can build flow screens that look and behave any way that you want. This feature is new in both Lightning Experience and Salesforce Classic. However, it only works for Lightning flow runtime.

Note: To use Lightning components, enable My Domain in your org.

What can you do with Lightning components in flow screens? Here are just a few ideas.

• Give users more intuitive navigation options.

• Add custom styling to the entire screen.

• Build dynamic screens with filtered fields.

This enhancement brings even more options to using Flows in LEX. However, this requires coding. I’d prefer to have more Flow declarative capabilities so one doesn’t have to learn more code.

Start Flows Dynamically from Apex

Previously, you could start a flow interview from Apex, but you had to hardcode the flow name in your method. Which means for every flow, you had to write a different method. With createInterview(), you can write one method to start an interview for any flow.

This is my favorite new feature so far. This will open all kinds of possibilites such as being able to create a dispatcher component that will be able to drive different users to different flow wizards based on configuration. Another option is to make more automation logic dynamic through configuration by letting an admin use flows to drive automation and which flows to use for different scenarios.

Lightning:recordEditForm and Lightning:inputField

These two new Lightning components look like a new way to create forms and that dynamically render the appropriate input UI for a field based on its field type. If this is so, I’ll have to see if this can be included in my field set form component.

What new features do you like? What do you think of the release.

Dreamforce 2017 Recap

Dreamforce this year was held Nov 6 – 9 in San Francisco. The last time for me was in 2012 so I was a little excited to go.


Overall, Dreamforce was a good experience. I met new people, some for the first time despite communicating on social media and Slack, and learned some new stuff.

Also, it was a bit meh. The crowds were larger than ever so getting anywhere was a chore and waiting in line for 2 hours to have a seat at the keynote was not appealing. The Booth staff at the developer area in Moscone West weren’t the people developing and managing those features like they had the last time I attended. No major new announcements and the ones that were announced were “incremental”.


  • Around 180,000 attendees
  • 3,000 sessions
  • 200 or so exhibitors
  • Numerous parties and happy hours
  • Lots of Announcements.

The Good

The people, aka the “Ohana”, are what made Dreamforce great for me. Everyone was friendly and collaborative. I had dinner and drinks with various colleagues I hadn’t seen in a while. I roomed with Bill Powell who was kind enough to share his hotel room and is a great guy.

Struck up some conversations with people who may turn into clients. I didn’t go to seek out new business but some business cards were handed out.

The Meh

Too Crowded

There were way too many people for me. Long lines and endless crowds made the venues, at times, very hard to navigate.

Booth Staff Not Experts

For someone who’s very technical and likes to dive deep on areas of interest, the people staffing the various booths in Moscone West were disappointing. In past Dreamforces, they were staffed by team members or managers from that particular area. For example, the Apex booth would be staffed by Apex developers and managers. This year it seemed to be staffed by volunteers or Salesforce employees who were voluntold to do so.

For example, when I asked the “Apex” booth person what’s new with the new “Apex” compiler, they said “I’m not sure since I don’t work in that department BUT we have this power point slide in case anyone asked about it”.

Incremental Product Announcements

My Lightning, My Trailhead, Commerce Cloud, and other product announcements were neat but didn’t wow me like past announcements.

As I sat watching the Key Note, I kept waiting for the major announcement or reveal that Salesforce had always done but then nothing. They kept talking about the “4th Industrial Revolution” and how Artificial Intelligence is going to do this and that but we’re just not there yet.

My Lightning lets you customize and brand Lightning Experience for your org with your company’s logo(s), colors, and layouts. Useful but I wish they would focus on making the performance better!

My Trailhead lets a company create their own content, quizes, and trails using TrailHead for internal use such as bringing a new employee up to speed. It’s kinda like an LMS but not as sophisticated. It’s also a paid add-on and not available yet.

Commerce Cloud is Salesforce new eCommerce platform where a company can sells their products and services using it while being totally branded and customized as needed. The demo I received was actually pretty good and it was highly configurable BUT this offering comes via a previous company acquisition and as such isn’t native to the Salesforce platform. All those products, accounts, and other information you have in Salescloud have to be replicated into the Commerce Cloud.

Closing Thoughts

Dreamforce is the biggest conference is the Salesforce ecosystem but perhaps it’s grown too big and another venue in another city would be better for the crowds and logistics. Instead of attending Dreamforce, I may attend smaller conferences such as TrailHeadDx or the various “Dreamin” events held by the community.

The biggest takeaway for me is that it felt like Salesforce is “maturing”. Their new product offerings are complementary, which is great, since someone could potentially run most, if not all, of their business solely on Salesforce. Also, Salesforce is polishing  their existing products and platform using features like “My Lightning” and “DX” for developers.

What did you think of Dreamforce?

Default Flow Picklist Value Without Duplicates

Flows are great but there are some quirks. One quirk is that a picklist input field can’t be prepopulated with the existing picklist field value from a record. There are some workarounds:

and there’s even an Idea: Flow – Pre-populate choices with dynamic values (variables).

The workarounds are good but one minor nuisance is that they cause the current picklist value on the record to be duplicated in the dropdown list.

Below is my solution that doesn’t have a duplicate option by using the PicklistValueInfo standard object in a Dynamic Record Choice.

High-Level Solution

  1. Query the record with the desired fields including the picklist field(s) using a Record Lookup or Fast Lookup.
  2. Create “Current Picklist Formula” that has an expression like “If(IsBlank(record.PicklistField), ‘Select an option’, record.PicklistField) so the formula can be used to dynamically use either the record’s picklist value if there is one or ‘Select an option’ if it’s blank.
  3. On a screen, create a picklist input with the following settings:
    • Choice – Use the current picklist formula as the label and stored value
    • Dynamic Record Choice – Use the PicklistValueInfo standard object to query all the picklist values except the currently selected value.
    • Set the Default to the “current choice”.

Industry Example

Let’s create a flow that allows one to quickly update the Industry field on an account record in Lightning.

Create recordId Variable

Query Account Record

Use a Record Lookup or Fast Lookup to query the account or desired record using the recordId variable. In the screenshot below, a Record Lookup is used. Note how the current industry is stored in the “Current_Account_Industry” variable.

Create Industry Default Choice Formula

Now, let’s create the “Industry_Default_Choice” formula that uses

  1. The “Current_Account_Industry” variable if it’s not blank.
  2. “Select an Industry”, otherwise.

Create “Selected Industry” Variable

Another quirk that drives me crazy is having to create a variable for a dynamic record choice to be saved to before it’s created. That’s needed because a dynamic record choice doesn’t allow one to create a variable on the fly like most other places.

Create a “Selected_Industry” variable like:

Create the Industry Input Field

Let’s start with the finished “Industry” dropdown list input field.

To create this, add a Dropdown List Input field to the desired screen.

Next, create a new “Choice” through the Add Choice link using the following settings:

The “Industry_Default_Choice” formula is used for both the Label and the Stored Value so they both can be dynamic. I.E. if the account has an industry, then it’ll be defaulted. Otherwise, “Select an Industry” is used.

Next, create the “Industry_Picklist_Choices” Dynamic Record Choice with the following settings:

Let’s break this down a bit. The “PicklistValueInfo” standard object contains all the picklist values for every picklist field on every object in the org. The “EntityParticleId” column has values in the format of <Object_API_Name>.<Picklist_API_Name>. In this example, the “Industry” field from the “Account” object is used so “Account.Example” is used to query all the Industry picklist records.

The second filter of “Value  does not equal  {!Current_Account_Industry}” will exclude the current industry, if there is one. If no industry is selected, all the active Industry picklist values are shown.

Now, simply use the {!Selected_Industry} variable as needed in the flow to do something with the selected value.


  • The list of industry picklist values are dynamic and change automatically without having to alter the flow as the Industry picklist values change.
  • The inactive picklist values are automatically excluded.
  • There’s no duplicate value in the list.


  • The picklist values available per record type aren’t honored. The user sees all the active picklist values.

What did you think of the solution?


Overview of Integrating with Salesforce

For a while now, I’ve been meaning to write about integrating with Salesforce. What motivated me to do it is a colleague asking me today: “Hey Luke. I have a system that has to write data back to Salesforce. What are my options?”

What’s an Integration?

An integration is when two or more systems talk to each other to accomplish something.

Two common integration types are

  • Single Sign-On (SSO)
  • Data Exchange

Single Sign-On (SSO) Overview

With Single Sign-On aka SSO, a user signs into one system, typically using their username and password, and then they’re able to sign-in automatically to other systems that are connected to that system without having to sign-in again.

The system where one signs in is known as the “Identity Provider”, or in some circles the “IdP”.

SSO Common Examples

  • A company’s website uses Salesforce as an Identity Provider. When someone tries to access a secure webpage on the website without being signed-in, they’re redirected to the Salesforce login page or community login page. After successfully signing in, they’re redirected back to the requested, secure webpage and are able to view it.
  • A Salesforce community allows one to login to the community using their favorite social media site such as Facebook, Google, Twitter, LinkedIn, etc. This is commonly known as “Social Sign-On”. It’s still SSO but with a social network as the identity provider.
  • An employee has signed in to their work computer and are automatically signed in to Salesforce. The most common example of this is when a company uses Active Directory and when you sign-in to your computer, you’re also signing in to the employer’s network. Since Salesforce can be configured to use your employer’s Active Directory for SSO, it’s a seamless experience to automatically sign-in to Salesforce.

SSO Technical Options Overview

API / Forms Authentication 

A system has a login page in it that accepts a username and password. When someone clicks “Sign In” or “Login”, the system calls the identity provider’s API passing in the supplied username and password, and if they’re signed in, their user information is returned to the calling system and they’re signed in. This used to be the most common way to do it before Open Id and other more secure protocols were created.

OpenID with OAuth2

In my experience, OpenId with OAuth2 is now the default SSO protocol used because it’s more secure and has become widely adopted. The High-Level handshake goes like this:

  1. User tries to access secure webpage and isn’t logged in so user is redirected to the Identity Provider’s website.
  2. The Identity Provider asks the user if they’d like to authorize that system to connect to this system. If they “allow it”, then they’re redirected to the Login page.
  3. User signs in and is redirected to the originally requested secure webpage on the other system along with a user token aka a special sign-in value.
  4. The original system takes this user token and asks the Identity Provider for the user’s information. The identity provider passes back the user’s information such as their name, contact information and possibly security information so the system knows what they have access to.

The primary advantage that this protocol has over “Forms Authentication” is that the users are only entering their credentials on the Identity Provider and the third-party systems never see a user’s credentials. This makes it more secure.

That’s the very quick gist of OpenId. Take a look at the OpenID with OAuth2 Documentation for more information.


SAML is another common SSO protocol but seems to be less adopted than OpenId. It’s pretty similar to how OpenId works but uses XML and assertions instead of JSON. See the SAML SSO Implementation Guide for more info.

Data Exchange

Data exchange is when two or more systems share data. There are many reasons why two systems would share data. Some common examples are:

  • The company’s e-commerce site integrates with company’s back office system to grab product information and to handle order processing.
  • A company replicates its data from many systems into a central data warehouse so that Business Intelligence software can do various analytics on it.

Data Exchange Models

There are three common models for exchanging data between systems:

  • Push
  • Pull
  • Middleware

Push Model

In a “Push” model, one system tells another system directly here’s the data to use and do something with it such as insert, update, or delete it.

This is most often used for “Real-Time” integrations where as soon as something happens in System A, System B is notified by System A. This allows the two systems to remain synchronized faster. For example, an order is submitted on the e-commerce site and then the site immediately tells Salesforce there’s a new order for that customer so it gets saved in Salesforce too. Another example is an account record is created in Salesforce so Salesforce does a callout to the data warehouse to replicate the data.

Pull Model

In a “Pull” model, one system asks another system directly for information.

This is often used for synchronizing large amounts of data that doesn’t have to be updated frequently because it doesn’t change often or it’s ok if the data isn’t exactly the same for a little while. One example is the data warehouse asking Salesforce for all the latest CRM data that’s changed in the last day.


A third system sits between two systems that have to exchange data but the two systems don’t directly communicate with each other. All data flows through the middleware. This can be beneficial because this specialized software is able to handle large volumes of data using various methods and typically doesn’t require any coding. They also usually have pre-built integrations for commonly integrated systems.


Data Exchange Methods

Now that we’ve covered the high-level models, let’s talk about how the data is exchanged.

Importing & Exporting with Files

This manual process requires someone to generate a file with the data to exchange in System A and then manually import it into System B. One common format is a comma separated value aka CSV file. One can even manipulate the data using common tools such as Excel before importing the data into the target system.

With Salesforce, one can use reports and even listviews to generate export files that can then be imported into other systems.

  • Usually easy and fast to implement.
  • Good for data that doesn’t have to update often.
  • Salesforce has decent out-of-the-box features for exporting and importing data.
  • It’s manual so people are involved so this can be slow and error prone.

Application Programming Interfaces (APIs)

An API allows another system to programmatically talk to it without human intervention.  There are different types of APIs such as REST and SOAP but for this overview, we’ll be skipping over those technical differences.

The primary benefit of having an API is that one or more external systems are able to use it to communicate with the system using a standard set of “services”.

Salesforce Enterprise / Partner APIs

The Enteprise and Partner APIs are standard APIs provided by and maintained by Salesforce so that external systems can Create, Read, Update, and Delete records in Salesforce. They come in SOAP and REST versions and are good for handling up to thousands of records at a time.

Salesforce Bulk API

This Salesforce provided API was designed to handle up to billions of records. It’s asynchronous and typically harder to use than the Enterprise or Partner APIs because multiple services have to be used to accomplish a single operation.

Salesforce Custom APIs

Developers can use Apex to create custom APIs that external systems can use to talk to Salesforce. This is typically done for more complicated scenarios and processing that the Enterprise, Partner, and Bulk APIs can’t handle alone.

API Pros
  • Multiple external systems can use the same API to communicate with the system.
  • No human intervention required.
  • Could potentially be easily consumed with standard middleware tools without coding.
API Cons
  • Creating good APIs are hard and time consuming because
    • they require good documentation so other developers can easily use them.
    • it takes a while to design and implement.
  • Often require developer level technical abilities to use.

Salesforce External Objects

This declarative option allows Salesforce to connect to an external system’s API, as long as that external system uses the OData protocol, to create, read, update, and delete the external system’s data from within Salesforce. The data is read and manipulated in real time from within Salesforce without having it stored in Salesforce.

  • Declarative and fairly easy to set up.
  • Uses object tabs and listviews to interact with the data.
  • Expensive. I hear it’s like $3-4 thousand per external object. If I’m way off, please let me know.

Salesforce External Services

This declarative option allows one to provide a “service schema file” to Salesforce using a particular format and Salesforce is then able to call an external system’s API using Flows. At the time of this writing, this feature is still in Beta.

  • Declarative and looks easy to set up.
  • ?? – Let me know in the comments since I haven’t used this option.


There are other ways to integrate such as using Canvas Apps and inbound email services but they don’t seem to be used much in my experience.

What did you think of this overview? Are there other integration options? Let us know in the comments.

Use showToast for taking Action After Lightning Record Edit

Whenever possible, I leverage the out-of-the-box Salesforce functionality to implement the desired functionality. One Lightning development feature I’ve used recently is the e.force:editRecord event. In a Lightning component, you can fire this event with a record id and that record’s default edit page will open in a new modal.

That’s great and saves a lot of custom coding, if that’s acceptable. However, after someone edits the record successfully, you’ll want to probably take some action such as updating the display to show the latest edits.

Problem: The force:recordSaveSuccess and force:recordSave don’t fire after the record is edited successfully, at least in Winter 18.

Solution: Use the showToast event to take action after a record is edited successfully.

In the handleToastMessage function, the code is checking for a specific “object saved message” and if it’s found, some specific actions are taken.

If you have a better way of doing this, please let us know in the comments!