Salesforce Winter 18 Release Review

Seems like yesterday that Salesforce released Summer 17 and here we are with Winter 18’s pre-release and release notes. Below is my review of the release notes. For a complete list of everything, check out the Winter 18 Release Notes PDF.

Lightning Experience Gets a New Look and Feel

Based on your feedback, we improved information density, legibility, contrast, and even added a splash of color. That means less time scrolling and scanning and more time focused on what matters most. This change applies to Lightning Experience only.

  • More information density and less white space, so you can see more of what you need without scrolling.
  • Improved legibility (using font size and color) to draw attention to what’s most important.
  • Better contrast between foreground and background, making it easier to scan and scroll while staying focused on what you need. We even added color and a background image inspired by our own Trailhead.

That’s a relief because when I implemented Salescloud for a customer, they commented about their being way too much white space so it’s great to see this change coming.

Navigate More Quickly with Keyboard Shortcuts

New keyboard shortcuts allow your users to be more efficient in both console and standard navigation Lightning apps. This change applies to Lightning Experience only. To view the available keyboard shortcuts, press:

• Windows: Ctrl+/

• macOS: Cmd+/

As someone who doesn’t like to leave the keyboard, thank you, especially with simply pressing “e” for editing and “Ctrl+S” for saving!

Set Up Person Accounts with Ease

Ready to start using person accounts? You picked a great time because we steamlined the enablement process. This change applies to both Lightning Experience and Salesforce Classic.

An automated process checks whether or not your org meets the requirements for using Person Accounts. The requirements are:

• At least one record type for accounts.

• Users that have read permission on accounts have read permission on contacts.

• Organization-wide default sharing is set so that Contact is Controlled by Parent or Account and Contact is Private.

From Setup, enter Account Settings in the Quick Find box, and then select Allow Customer Support to enable Person Accounts. After we confirm that your org is ready for Person Accounts, we’ll send an email with additional information about logging a Support case.

Salesforce, I can’t thank you enough for this! I wish you had done this about 5 years ago! At my last employer, our package used Person Accounts heavily, and waiting for Salesforce to enable Person Accounts through a case would usually take 1-2 days. That was even after we streamlined the case body to have all the info they always required, especially the “YES, I am the admin and understand this can’t be turned off once enabled”.

In fact, Ted Husted and I did a “Person Accounts in Action” white paper describing Person Accounts in-depth and published it but have to find it.

Various List View Enhancements

  • Sticky column widths – You can resize a list view’s column width and it remains that size when you return to it later. You can reset it to its original size too.
  • Edit More Records at Once with Mass Inline Editing – You can now update up to 200 records without leaving a list view! Select multiple records, click edit next to the field you want to update, enter the new value and click apply. It’s essentially the same as it worked in Classic. Glad this is finally added because this will really increase a power user’s productivity.

Merge Person Accounts in Lightning Experience

Sales reps can now view duplicates on person accounts in Lightning Experience just as they can on business accounts, contacts, and leads. Users with permission can merge person accounts, too. This change applies to Lightning Experience only.

1. In Setup, make sure that a duplicate rule for person accounts is active.

2. Configure the Potential Duplicates component in Lightning App Builder. Your sales team sees this alert when they view a person account with a duplicate.

I so wish this was available sooner like so many other things. In the past, I had to resort to customizations and other means for this. I wish this was available in Classic too but this is a start!

Better Email Integrations

The Gmail and Outlook integrations are getting better with every release! Task management and two-way syncing are amazing and setting it up is all declarative.

Wave Analytics Renamed to Einstein Analytics

They renamed it and are now including Einstein Discovery. There’s a ton of functionality here and it’s on my to-do list to dig into.

Embed Flows in Lightning Community Pages

Very interesting! This will allow all kinds of new interactions in Communities. Am excited to see how this pans out.

Create Communities in Enterprise, Performance, and Unlimited Editions — Even Without Communities Licenses!

All Enterprise, Performance, and Unlimited orgs can now create up to 100 communities, even without purchasing a Communities license. To start creating your community, first enable Communities in your org. After you create a community, give access to internal users with Salesforce user licenses. Guest users without a license have limited access to your community. Purchase Community Cloud licenses for more access or page views, based on your business needs.

Interesting. I wonder if internal users can now have departmental communities within Salesforce?

Dynamic Lightning Pages

Now you can control when a component appears on a record page by adding filter conditions and logic to its properties. No need to add anything to your custom components. It’s all handled by the Lightning App Builder. For example, construct a filter that causes a rich text component on an opportunity page to display when the Amount is greater than $1 million.

Component visibility filters are supported for standard components, custom components, and components from AppExchange. If you don’t define a filter, the component displays on the Lightning record page as usual. When you define one or more filters and set the filter logic for a component, the component is hidden until the filter logic criteria are met.

Admins can now declaratively define criteria for when a Lightning component is visible on a page through Lightning App Builder. Very nice!

Take Lightning Page Customization to a Whole New Level with Custom Page Templates

Now you’re no longer limited to the standard templates available for Lightning record, app, and Home pages. Take your business needs in hand, and create a custom page template of your own that has the structure and components that you define. Add as many regions as you need, and even custom styling. This feature is available in Lightning Experience and all versions of the Salesforce1 mobile app. It all works by using Lightning components.

Every Lightning page includes a template component that defines the page’s regions and what components it includes. Now you can create a custom Lightning page template component and make it available as a custom page template in the Lightning App Builder’s new page wizard.

There are new interfaces and tags for the .cmp and .design files that help you define the template’s structure, regions, and included components. Each page type has a different interface that the template component must implement.

• lightning:appHomeTemplate

• lightning:homeTemplate

• lightning:recordHomeTemplate

This definitely helps with UI and UX consistency, especially for those building large, custom applications.

Launch a Flow from an Object-Specific Action (Beta)

Add flows to the action menu on your Lightning pages without hunting down the flow’s URL. When you create a flow action, you can pick from a list of available flows rather than enter the flow URL manually. This feature is available in Lightning Experience and all versions of the Salesforce1 mobile app.

Tip: If your flow needs the ID of the record that it’s operating on, don’t worry! Salesforce sends the record ID to the flow as long as you have a Text input variable called recordId.

Thank you thank you thank you! Now, typical workflows can be even more specific per object! I have a few use cases for a client that I can apply this to. I wish this was available in Classic though as with so many of the other new features.

Configure a Flow to Wait for a Platform Event to Occur

You can now subscribe to platform events in a flow Wait element. With platform events, a flow can wait for something to occur, inside or outside your Salesforce org. Previously, a flow could wait only for a relative or absolute date/time value. This feature is new in both Lightning Experience and Salesforce Classic.

This opens up a lot of interesting possibilities since one can now use Flows in this Pub-Sub architecture. This is now on my backlog to experiment with. What use cases can you think of for using this?

Salesforce DX: The New Frontier for App Development (Generally Available!!!)

With a focus on source-driven development, Salesforce DX makes it easier for developers to build together and continuously deliver using the tools that make you most productive. Salesforce Developer Experience (Salesforce DX) will be generally available in mid-October 2017.

Salesforce DX is built on these core principles:

• Source code drives everything.

• Metadata and code are modular.

• Environments are easily created and disposable.

• Development is organized around team collaboration.

• Development is based on open standards and extensibility.

• Flexible packaging supports an agile distribution model.

• Processes and tools facilitate continuous integration and continuous delivery.

Salesforce DX shifts the source of truth from the org to the version control system. By managing your Salesforce code outside of the runtime environment, you can harness industry-standard tools and drive team collaboration during the development and deployment process.

Whether you’re an individual developer or working as part of a large team, Salesforce DX provides an integrated, end-to-end life cycle designed for high-performance agile development. And best of all, we built it to be open and flexible so that you can build together with the tools and practices you know and love.

Simply awesome. This has to be my favorite Winter 18 release feature, by far. Getting changes from one org to another has always been a challenge but this should makes things easier. Additional investigation is needed to see how this can be done with Admins as well.

Lightning Data Service is GA

Spectacular! This is good for standard CRUD operations but for more advanced interactions, APEX is still needed.

Various New Lightning Base Components

There are around 30 new Lightning Base components available. Here are a few that really look interesting:

  • lightning:datatable – More easily display tabular data.
  • lightning:dualListbox – The Classic multi-picklist UI comes to lightning. I wish this didn’t.
  • lightning:flow – Represents a lightning flow in Lightning. Now you can embed flows into custom components and apps. Very nice!
  • lightning:fileUpload – Enables mutiple file to be uploaded to a record. It also includes drag-and-drop and filtering by file types. I wish this existed a couple months ago when I created something similar.
  • lightning:helptext (Beta) – An icon with a text popover. The popover is displayed when you hover or focus on the icon that’s attached to it.

Bulk API 2.0 Generally Available

Bulk API 2.0 uses the same secure, high-performance REST framework as the REST API, which provides features like OAuth authentication and CORS support. Bulk API 2.0 also provides a streamlined interface for data operations by breaking data files into batches automatically. Upload your data and specify an operation. Salesforce then determines the most efficient way to batch the data.

This is my second favorite new feature. The new API automatically breaks up data files into batches automatically. Thank you. I spent a decent amount of time in the Salesforce Bulk API Starter project getting that to work. Now updating that project to use the 2.0 API is on my backlog!

What features were noteworthy to you?











Salesforce is a great company with excellent products and an even better platform. One area that needs more attention is knowing what’s happening in your Salesforce org without enabling Salesforce debug logs. Has a client or a user contacted you saying X is not working and they don’t know what’s going on so you turn on the debug logs hoping for more information and it’s not helpful?

It happens more often than not and troubleshooting it is hard.

Meet Salesforce Logger

This new Logging framework allows one to add logging to their customizations which can then be saved to one or more logging repositories as the customizations are run. Out of the box, it supports saving logs to the debug log, a log custom object, and/or to Loggly, a separate SAAS logging service. If more is needed, one can implement their own persistence logic to save logs wherever they’re needed.

This allows one to monitor the logs to see what errors are happening and how the customizations are being used or not.


I’m currently offering this as a free Beta package to pilot testers so they can test it out and provide feedback. If you’re interested in being a pilot tester, follow the instructions at Salesforce Logger Pilot to install, configure, and use the Salesforce Logger Beta package.

When you’re done, Contact Me about what’s good, what needs improvement, how much you’re willing to pay to use this package in production, and any other feedback you’d like to give.

Wanna Try it Out?

Follow the instructions at Salesforce Logger Pilot to install, configure, and use the Salesforce Logger Beta package.

Loggly Example

Here’s an example of a flow error that logs the error to Loggly using a custom FlowError fault handler using an apex class. Am debating if this should be added to the product or not because I’m not sure if this will be more helpful than the regular Flow error email.

What do you think?

Log Custom Object Example

Here’s the same flow error saved as a Log record in the Log__c custom object.

Lightning Field Set Form Component

UPDATE: Checkout Version 2 of the Field Set Form

For learning purposes, I created a Lightning Field Set Form component that renders a one column form of inputs for a set of fields for a given SObject where the field inputs are driven by a specified field set on that object. This code was influenced by the How to use Field Sets with Lightning Stackoverflow post.

Use Cases

This component can be used to either update a record or create a new record.

Updating a Record

To update a record on a standard record page,

  1. Create a field set on the object that specifies the fields to edit.
  2. Place the FieldSetForm component on a record page and specify its Field Set Name on the designer tab.

To update a record from a custom component,

  1. Embed the <c:FieldSetForm /> in the custom component.
  2. Set the recordId and fieldSetName attributes with the record id and field set name to use.

Creating a Record

  1. Add the component to the desired location.
  2. In the designer, specify the object name and field set name.


  • Needs to be enhanced to have better support for Relationship fields (Lookups & Master-Details), picklists, and multi-picklists, and probably other data types too.
  • Needs apex test code written for it.
  • Needs better error handling. It currently only shows the first error returned on save.

Notable Differences From StackOverFlow Post

  • The handleValueChange method isn’t needed to bind the input values back to the record because the cmp.getReference(‘v.record’ + field.APIName) takes care of that automatically.
  • There was a bug with the config where the same config was being used for the same type so if you had multiple fields with the same type, you’d see the same field multiple times. This was fixed by cloning the config for each field using the JSON.parse workaround.
  • Added the ability to save the record back automatically with new and update support.
  • Was able to eliminate the form attribute because all components inherit the body attribute.


This was created for learning purposes. Whenever possible, use other standard components that provide similar functionality like the force:recordEdit component that does similar functionality.

Component Markup

Component Controller

Component Helper

Component Design

Apex Controller

Apex Field Class

Interesting Salesforce Id Information

Today I want to share some information regarding Salesforce record Ids.

Quick Primer

Each record in Salesforce has a unique record id. Record ids are either 15 or 18 characters in length and each character is base 62 encoded which means a character can be the numbers 0-9, lower case letters a-z, or capital letters A-Z. That means there are 6215 or 768,909,704,948,766,668,552,634,368 possible record ids.

Object and Pod Info Encoded into Ids

The first three characters of an Id identify the object and are the same across orgs. For example, 001 is the prefix for account records. See Daniel Ballinger’s Obscure Salesforce object key prefixes Post for a thorough reference of them all. That means a Salesforce org can have 238,328 standard and custom objects in it. Would be interesting to see what happens if someone tried to create that many objects in an org.

The fourth and fifth digits identify the Salesforce pod or datacenter where the record was created. The fourth one is the primary identifier but if needed, the fifth digit is used. The 6th digit is reserved and currently not in use so it is 0 for now. The last 9 are a really big number to help identify the record. That means for any given object, there are 629 or 13,537,086,546,263,552 possible records it can hold.

For more info, check out the What are Salesforce Ids composed of StackExchange post.

18 Digit Id Case-Insensitive for Comparison Only

One can take a 15 digit record id, apply an encoding algorithm to it, and make it into an 18 digit id. Why would one do that you’re probably thinking… Well, certain external programs may treat 001E000001LaoNK and 001E000001LaoNk as the same value when comparing them even though they’re different. Did you notice the difference? To solve this, Salesforce provides the 18 digit version of the Salesforce record ids when querying through the APIs so that external programs don’t run into this issue.

Given the above and reading various documentation, some people think that the 18 digit ids are case-insensitive so one can simply upper case or lowercase everything and the ids will still work in Salesforce. This is false. It’s only true when comparing two Salesforce record Ids that haven’t been altered.

Easily Open a Record Using Just Its Id in Classic

Have only a Salesforce record id and want to open it? Open Salesforce Classic, paste the record id after the domain in your browser’s url and it should open the record. For example, if my org’s domain is, I can open a record by using<record_id_here>.

Unfortunately, this doesn’t work in Lightning experience. If there’s another way to do it, please let me know!

Query Polymorphic Relationships For A Particular Object using SOQL

Some standard objects have a polymorphic relationship which means they can be tied to any parent object. For example, an activity record’s What Id field. There are times when you’d like to use SOQL to query activity records for a particular object. Unfortunately, Salesforce doesn’t allow the “like” keyword to be used with Id fields so you can’t do something like this:

BUT you can use greater than and less than operators with Ids. This means you can select all activities tied to a given object by comparing the ids greater than or equal to the object’s minimum record id value and less than or equal to the object’s maximum id value. For example, let’s say we wanted to query all the account tasks. That can be done like this:

What other information do you have on Ids?


It’s been a while since I’ve posted anything on Lightning but now that I’m back in the thick of it, here are some additional tips I’ve learned from doing some more advanced, for me at least, Lightning work.

Checkout my Lightning Component Dev Tips and Lightning Component Dev Tips 2 for other tips.

Component.getReference For Dynamically Building References

getReference returns an object that can resolve itself at runtime or be able to bind to attributes. For example, you can dynamically attach event handlers to a component at run time.

Another example is dynamically binding to fields at run time.  The use case is you have a field set or other metadata that defines a list of fields to display on a lightning component. If an admin wants  to update the list of fields, they can easily do so without a developer updating the code. Unfortunately, this is not as straight forward in Lightning as it was in Visualforce. The following is NOT allowed to dynamically show a record’s fields.

getReference to the Rescue

When the list of fields are returned from an Apex callout, where the callout gets them from a field set or some other metadata, one can use the getReference function on the component to dynamically create a reference that will resolve to retrieving the field’s value from the record. Below is an example of that.

Now that the field value has been bound to the FieldValue on the Field, it’s a simple matter of iterating over it in the markup. Of course, you’d probably want to format the output further depending on the field’s type. For example, localizing a datetime or date field.

Another place where this was helpful for me was dynamically creating an input component and binding it to the component’s value field. This allowed for the two-way binding to still work for dynamically created components so that when the input value’s changed, it would also update the record’s value to easily allow the record to be upserted via an action.

Using the above helped in the creation of a FieldSetForm component that builds a dynamic set of inputs for a given SObject record driven by a field set.

Use “and” and “or” keywords in place of “&&” and “||”

The && and || operators are now allowed in the {!  } component markup for some reason. Instead, use the “and” and “or” functions that take a list of predicates and evaluate as expected.

Event Parameters Are Pass-By-Value

When passing a Javascript object through a fired event in one component as an event parameter and it’s modified on another listening component’s event handler, the object’s modified state isn’t visible on the original component that fired the event.

In other words, an event’s parameters are pass-by-value and are copied instead of pass-by-reference.

Can’t Create div, span & Other HTML elements in CreateElement or CreateElements

The ‘Type’ parameter to CreateElement and CreateElements must be an Aura or Lightning component. It can’t be a simple HTML element such as “div” or “span”. Even though they get created successfully, they don’t render on the page.

What other tips do you have? Let me know in the comments.