Salesforce Winter 22 Release Review

Winter is coming! Not the season but the Salesforce Winter 22 Release. Here are some notable items and my thoughts on it.

Welcome to Einstein Search: Now on by default

Einstein Search is at your service. It’s enabled by default at no extra cost. Users can search just like they’re used to. Nothing’s going away with Einstein Search, but search is getting smarter. Einstein Search adds personalized search results, record previews from the search box, and natural language searches.

Where: This change applies to Lightning Experience and all versions of the Salesforce Mobile app in Essentials, Professional, Enterprise, Performance, and Unlimited editions.

Winter 22 Release Notes

This is awesome. Searching is one of the most common actions and doing it better is a welcome addition. It would be nice if SOSL (Standard Object Search Language) automatically inherits this too but it doesn’t appear to be the case. Being able to do better searching for custom functionality would be great too.

Build More Interactive Lightning Pages with Dynamic Interactions

Now you can create applications with components that communicate and transform based on user interactions, all in the Lightning App Builder UI. With Dynamic Interactions, an event occurring in one component on a Lightning page, such as the user clicking an item in a list view, can update other components on the page.

Where: This change applies to Lightning Experience in Group, Essentials, Professional, Enterprise, Performance, Unlimited, and Developer editions.

How: To get the most out of Dynamic Interactions, admins and developers work together.
Developers write custom Lightning web components that power the dynamic interactions. The developer defines the events that are supported by a component and then exposes them in the Lightning App Builder. Then for each event, admins can create interactions between the source and target components using a new Dynamic Interactions UI in the Lightning App Builder properties pane.

If a component has events exposed for it, its properties pane has two tabs. The Properties tab contains the component properties that you’re familiar with. The Interactions tab is new for Dynamic Interactions. It lists all the events that the developer exposed for the selected component and any interactions that have been configured for each event.

Winter 22 Release Notes

This is very nice! This lets developers create even more reusable components that Admins can use throughout Salesforce without as much development by letting the developer define the events that can be invoked and then an admin tell the component when to perform those event when other interactions happen. It makes me wonder if this could be used to more easily communicate with utility bar components?

Hide More Personal Information Fields from External Users

To prevent external users, such as portal or partner users, from viewing personal information in your user records, enable the Enhanced Personal Information Management permission. Salesforce then blocks view and edit access to 20 fields that are considered personal information.

You can configure which fields you consider personal information from User Management Settings. This permission replaces the less-configurable Hide Personal Information setting, which will be retired in the Winter ’23 release.

Where: This change applies to Lightning Experience in Enterprise, Performance, Unlimited, and Developer editions.

Why: When you enable the Enhanced Personal Information Management permission, these fields are masked to external users.
• About Me
• Address
• Alias
• Company Name
• Department
• Division
• Email
• Email Sender Address
• Email Sender Name
• Email Signature
• Employee Number
• Extension
• Fax
• Manager
• Mobile
• SAML Federation ID
• Phone
• Title
• User Photo badge text overlay
• Username

How: You can click to access a user record field directly from this org permission in User Management Settings. Add or remove Personal Info from the field’s Compliance Categorization area. In the Winter ’23 release, this setting will be enforced and the Hide Personal Information setting will be retired.

Winter 22 Release Notes

This provides much greater flexibility over what user information that portal and partner users can see!

Control Access to Sensitive Data with Restriction Rules (Generally Available)

Secure your data and boost productivity by permitting your users to see only the records necessary for their job function. Create restriction rules to control which subset of records you allow specified groups of users to see. Restriction rules are available for custom objects, contracts, tasks, events, time sheets, and time sheet entries. This feature, now generally available, includes some changes since the last release. You can now create and manage restriction rules in Setup as well as with Tooling and Metadata APIs.

Where: This change applies to Lightning Experience in Enterprise, Performance, Unlimited, and Developer editions.

How: To create a restriction rule, navigate to Object Manager in Setup. Select the object that you want to add a restriction rule for. Click Restriction Rules. Name and describe the rule and activate it. Select a user field and choose filter settings to determine which users the rule applies to. Then, select a record field and choose filter settings to determine which records are accessible.

Winter 22 Release Notes

This is another welcome addition to the platform! Previously only an additive record sharing model was possible. That meant one would likely have to use private sharing with role hierarchy, sharing rules, enterprise territory management, and other sharing options to grant the appropriate record access. That was especially challenging for mostly public information except for certain users. These restriction rules use a “Deny” also security model to deny record access for certain users based on certain criteria being met. This helps with the situation where everyone has access except X.

View Dependencies for Lightning Web Components

Use the dependencies tree viewer to see which custom components and Apex classes that a Lightning web component uses. You can quickly see the structure of a component and navigate to the source for its dependencies.

Where: This change applies to Lightning web components in Lightning Experience.

How: From Setup, in the Quick Find box, enter Lightning Components, and then select Lightning Components.
• To see its dependencies on the detail page, select a Lightning web component.
• To see the details for one of the dependencies, click a link in the Name column.

The dependency tree shows up to three levels of dependencies for a component. For example, you can see a component and its nested child, grandchild, and great-grandchild components. To view deeper dependencies, click a link in the Name column for one of the nested components.

Winter 22 Release Notes

This is probably most useful for Admins who want to see what dependencies an LWC has. Most developers are probably using an IDE so it’s a lot easier to see them there and navigate.

Limit for Number of Actions in a Boxcar Request was Added

The Lightning Component framework now returns a 413 HTTP response status code if there are more than 2,500 actions in a boxcar request. Previously, there was no limit and a request with a larger number of actions was rare but led to a slow response time. If a user sees this error, consider redesigning your custom component to follow best practices and reduce the number of actions in a request.

Where: This change applies to Aura and Lightning web components in Lightning Experience and Salesforce Classic.

How: The framework queues up Apex actions before sending them to the server. This mechanism is largely transparent to you when you’re writing code, but it enables the framework to minimize network traffic by batching multiple actions into one request (XHR). The batching of actions is also known as boxcar’ing, similar to a train that couples boxcars together. The framework uses a stack to track the actions to send to the server. When the browser finishes processing events and JavaScript on the client, the enqueued Apex actions on the stack are sent to the server in a batch.

Winter 22 Release Notes

If a lightning component is doing say more than 20 AJAX requests simultaneously, there are likely optimization opportunities. Generally speaking, the two slowest operations are network and database operations. Minimize those as much as possible and you’ll likely see a good performance boost. If possible, fetch all your data in one AJAX call when the LWC opens and go from there. 2,500 actions seems too high to me so they’re being generous.

Use the valueOf() Enum Method to Convert a Specified String to an Enum Constant Value

The valueOf() enum method converts a specified string to an enum constant value. An exception is thrown if the input string doesn’t match an enum value. In previous releases, using this method resulted in a runtime error.

Where: This change applies to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions.

How: You can use the method for both system and user-defined enums. This example uses the method to convert a string to a known season enum value.

public enum Season {WINTER, SPRING, SUMMER, FALL}
string currentSeasonInput = ‘winter’;
Season currentSeason = Season.valueOf(currentSeasonInput);

Winter 22 Release Notes

A nice-to-have for when enums are used. This saves the boiler plate code for mapping a string value back to its Enum.

Use Mock Responses to Test Salesforce Functions

Apex now supports mock testing of Salesforce Functions. Use the existing Test.setMock() method with the new
FunctionInvokeMock interface and MockFunctionInvocationFactory class methods to mock test Salesforce Functions.

Where: This change applies to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions. Function testing methods are only enabled in Salesforce orgs that are configured to work with Salesforce Functions.

Why: By default, test methods don’t support invocation of Salesforce Functions. Use mock responses to support effective testing and mocking of Salesforce Functions integrations, while also meeting the minimum 75% Apex code coverage requirement.

How: Provide an implementation for the Functions.FunctionInvokeMock interface to specify the response sent to the respond() method, which the Apex runtime calls to send a response for the function.

@isTest
public class FunctionsInvokeMockImpl implements functions.FunctionInvokeMock {
public functions.FunctionInvocation respond(String functionName, String payload) {
// return mock success response
String invocationId = ‘000000000000000’;
String response = ‘mockResponse’;
return functions.MockFunctionInvocationFactory.createSuccessResponse(invocationId,
response);
}
}
Next, instruct the Apex runtime to send this mock response by calling Test.setMock() in your test method:

Test.setMock( functions.FunctionInvokeMock.class, new FunctionInvokeMockImpl())

The first argument to Test.setMock() is functions.FunctionInvokeMock.class, and the second argument is a
new instance of your implementation of the FunctionInvokeMock interface.

Winter 22 Release Notes

It’s nice that there’s a standard way to mock out Salesforce functions, especially now that Salesforce functions is generally available!

Call Invocable Actions from Apex (Developer Preview)

Invocable.Action is a new Apex class that allows you to call invocable actions from Apex code. For the developer preview, this feature is available only in scratch orgs.
Where: This change applies to Lightning Experience and Salesforce Classic scratch orgs.
Note: Feature is available as a developer preview. Feature isn’t generally available unless or until Salesforce announces its general availability in documentation or in press releases or public statements. All commands, parameters, and other features are subject to change or deprecation at any time, with or without notice. Don’t implement functionality developed with these commands or tools.

How: To enable this feature in your scratch org, add a reference to CallIAFromApex in the project-scratch-def.json file in your SFDX project.

Winter 22 Release Notes

The release notes provide two examples. One where Apex code is invoking a Standard Action for a chatter post and one for calling apex invocable actions. Neither of those seem worthwhile because there’s already chatter related Apex code one can use and one can directly invoke the apex for the invocable action so this seems like unnecessary overhead. If someone knows of a good use case for this, please share in the comments!

Unleash the Power of Elastic Compute with Salesforce Functions (Generally Available)

Salesforce Functions empowers teams to focus on delivering apps and business logic fast instead of managing infrastructure. Your Salesforce app can now use additional programming languages and open-source or third-party frameworks, saving you development time and effort.

Where: This change applies to Lightning Experience, Salesforce Classic, and all versions of the mobile app in Professional, Performance, Unlimited, and Developer editions.

When: We’ll announce when Salesforce Functions becomes generally available. Look for further announcements and details on developer.salesforce.com and in the Salesforce Functions Trailblazer Community.

Why: With Functions, you can deploy code in a serverless environment, enabling you to run computationally heavy operations on demand. Functions also enable teams to accelerate productivity by making it easy for developers to adopt common industry languages and their supporting ecosystems, as well as the development tools of their choice. Salesforce Functions are fully managed by the Salesforce Platform, which takes care of everything else necessary to invoke your code in a secure, auto-scaling environment.

How: Functions are just another element of your Salesforce project and are deployed easily with simple Salesforce CLI commands. Write JavaScript, Typescript, or Java code that uses Salesforce Functions SDKs to communicate with your org. Then, invoke your Function using Apex, and the Salesforce Functions infrastructure authenticates and runs your Function on demand.

Winter 22 Release Notes

Being able to run computationally expensive code not subject to limits running in the context of the running user using other supported programming languages is huge! This will allow much greater flexibility when designing apps and expand the developer pool. Last I heard this is a paid add-on but what’s unclear is how much!

Connect a Record-Triggered Flow to an External System Using an Asynchronous Path

Finally, you can use a record-triggered flow to integrate with an external system and update external objects—without writing any code. Add an asynchronous path that runs after the original transaction for the triggering record is successfully committed. Now your record-triggered flows can perform actions that were previously limited by transaction boundaries. For example, use an asynchronous path to post a message to Slack, update a record in Heroku, or place an order using a third-party fulfillment system. Both asynchronous and scheduled paths are subject to the same asynchronous per-transaction Apex limits.

Where: This change applies to Lightning Experience and Salesforce Classic in Essentials, Professional, Enterprise, Performance, Unlimited, and Developer editions.
Why: In Spring ’21, scheduled paths became available in record-triggered flows. Now we added asynchronous paths that run in the background and don’t delay the execution of your original triggered transaction. Use an asynchronous path to execute a long-running operation, such as a callout to an external web service or any operation that you want to run on its own time. You can also use an asynchronous path to avoid the mixed DML error. For example, in a flow that’s triggered to run when an opportunity is created or updated, use an asynchronous path to update a value on a user record. You can’t define a time for an asynchronous path to run as you can for a scheduled path. And in situations when system resources are unavailable, the execution of an asynchronous path will be delayed.

How: Asynchronous paths are available for record-triggered flows that run after the record is saved. Open the Start element. Configure the flow to run only when a record is updated to meet the condition requirements, or select the Is Changed operator in a condition. Select Include a Run Asynchronously path to access an external system after the original transaction for the triggering record is successfully committed.

When a new or updated record triggers your flow to run, an asynchronous path is queued until it runs. You can monitor an asynchronous path on the Time-Based Workflow page in Setup.

If you deselect Include a Run Asynchronously path, an asynchronous path is removed from your flow.

Winter 22 Release Notes

This is the flow equivalent of Apex’s future or queueable and lets one run some operation after a record gets saved in seperate execution context subject to the same async apex limits. This would mostly apply to mixed-DML operations and external callouts but can be useful in other situations too such as avoiding limits. One has to be careful though because async operations can lead to partially committed data and error handling can be tricky.

Call Another Flow from a Record-Triggered Flow Using a Subflow Element

You asked for it! Subflow elements are now available for record-triggered flows that run after a record is saved or before a record is deleted. Now you can break your automation into building blocks and reduce the complexity of a flow. From within a flow, call another reusable flow to perform a common task. For example, when you create an opportunity, call an autolaunched flow that determines which region to assign the opportunity to.

Where: This change applies to Lightning Experience and Salesforce Classic in Essentials, Professional, Enterprise, Performance, Unlimited, and Developer editions.

How: Create an autolaunched referenced flow that performs a common task. As necessary, create input and output variables that are sObjects of the same type. Then open a record-triggered flow. Drag the Subflow element onto the canvas. Search for and select the referenced flow. Assign the values of the $Record and $Record__Prior global variables to the input and output variables. When the record-triggered flow executes the Subflow element, the triggering record’s values are available in the referenced flow’s $Record and $Record__Prior
global variables.

Winter 22 Release Notes

This is another huge improvement! A sub-flow is the apex equivalent of functions. One can now define an autolaunched flow and reuse it in different record-triggered flows except before-save insert and before save update flows. This will help reduce and manage complexity a great deal. HOWEVER, for automation that more than moderately complex AND one has developer skills or developers on staff, apex code should be used because its complexity tolerance is higher and it’s more performant!

Supercharge Scheduled Paths with Enhancements with Enhancements for Minutes, Batching, and Limits

It’s been a minute since you asked, but we heard you. Now you can specify in minutes the time that you want a scheduled path to run. You can also set a batch size to improve performance and avoid hitting Apex governor limits. And now the less restrictive asynchronous limits apply to scheduled paths, making it easier to complete complex operations without hitting limits.

Where: This change applies to Lightning Experience and Salesforce Classic in Essentials, Professional, Enterprise, Performance, Unlimited,
and Developer editions.

Why: Previously, you could specify only a number of hours or days before or after the time source for a scheduled path to run. The time
source for a scheduled path is either when the triggering record is created or updated, or the value of a record date/time field.

Note: In some cases, a scheduled-path interview won’t execute until after system resources become available.
And to help avoid hitting a per-transaction Apex limit with a scheduled path, now you can specify a batch size for it. The batch size is the number of records that a path can process at the same time. The default and maximum value is 200, and the minimum is 1. For example, if you specify a batch size of two and seven records are scheduled to be processed in the same time interval, Flow Builder groups them into four batches.

Scheduled paths and asynchronous paths are batched differently. In a scheduled path, all the records that meet the conditions and are scheduled to be processed in the same minute are grouped up to the batch size into one batch.
In an asynchronous path, a set of records is always processed together in one batch and never combined with other records. For example, if 20 accounts are updated in a single update operation, those same 20 accounts are processed in one batch.

Winter 22 Release Notes

One no longer has to use hacky hourly logic to say run 5 minutes from now. The batch size is nice too. It would be nice if it applied to async paths too.

Send Outbound Message from Your Record-Triggered Flow

Outbound messages are available as a core action in Flow Builder. Send a SOAP message from a record-triggered flow to a designated endpoint. For example, notify an external service when a high-priority case is created. Perhaps you used outbound message actions with workflow rules and approval processes. Now outbound message actions are available for record-triggered flows that run after the record is saved.

Where: This change applies to Lightning Experience and Salesforce Classic in Essentials, Professional, Enterprise, Performance, Unlimited, and Developer editions.

Winter 22 Release Notes

This is another welcome addition. This was the last primary reason one would consider a workflow rule since process builder and flows didn’t have Outbound Messages as an option. Going forward, one should not consider using a Workflow Rule since that functionality has been replaced by Flows.

Customize Button Labels in the Flow Screen Footer (Beta)

Customize Button Labels in the Flow Screen Footer (Beta). In Flow Builder, you can now easily customize the Previous, Pause, Next, and Finish button label text. With customized screen navigation options, you can let a user know what to expect when the user clicks the button. Previously, to customize the footer labels, you built a
custom component.

Where: This change applies to Lightning Experience and Salesforce Classic in Essentials, Professional, Enterprise, Performance, Unlimited, and Developer editions.

Note: This feature is a Beta Service. Customer may opt to try such Beta Service in its sole discretion. Any use of the Beta Service is subject to the applicable Beta Services Terms provided at Agreements and Terms.

Why: Sometimes you need a flow screen’s navigation buttons to more accurately indicate what happens when a user clicks a button. For example, you’re designing a screen flow and using a Create Records element that creates a contact record. On the flow screen, you change the Finish button to Create Contact and the Previous button to Go Back. After the user clicks Create Contact, the screen flow creates the contact record.

Winter 22 Release Notes

Another welcome addition that I’ve created custom components for and recommend people use the unofficialSF Navigation Button.