Overview of the standard functionality
Before we dive into the details of lwc-das let’s first have a look at the standard functionality of LWCs and the Lightning App Builder.
Lightning App Builder
The Lightning App Builder provides a straight forward way to arrange several Lightning Components (Lightning Aura Components and Lightning Web Components) into a single page, which then can be used either as a record page, home page or app page. All this can be done using drag & drop in a visual editor and does not require any coding.
While Salesforce provides many standard Lightning Components out of the box, not all of them are available in the App Builder. The reason for this is, that there are two different types of standard components.
While each of these components work in their own world, some of them have counterparts which make them available for both roles — developers and admins.
Besides the existing standard components developers can build their own components. These are by default available to use in development inside of other components, exactly like the programmatic standard components. However, developers can enable these components to show up in the Lightning App Builder, which allows them to be used by developers and admins alike. Developers can enable the configuration of these components from within the Lightning App Builder by using public properties.
Communication between single components
The most common use cases require some kind of connection between the different components. This way, one component can react on a state change of another component. The Lightning Web Components framework provides several ways to establish these kind of connections (Public Properties, Public Methods, Events, Lightning Message Service). However, just the Lightning Message Service is suitable for use in the App Builder. To make it easier for us to understand the concept behind the Lightning message service let’s introduce the following fictional requirements for an app we need to develop.
- Display a selectable table with all available accounts on the left of the screen.
- Display another table on the right side of the screen, which displays only these contacts, that belong to the currently selected accounts.
- Beneath each of the tables display a map, which shows the location (BillingAddress, MailingAddress) of the currently selected records. In each of these maps it should be possible to select one location at a time.
- Beneath each of the maps display the account/contact data of the record selected in the map.
The following screenshot gives an overview of the desired functionality.
When designing the implementation for this requirement a developer has two choices.
- Developing a single parent component which itself is composed of several child components. The communication between the child component is handled by the parent component.
- Developing six separate components which can then be composed to an app using the Lightning App Builder and communicate with each other by leveraging the Lightning message service.
For this article, we will concentrate on the second approach here.
The following illustration shows a rough overview of the typical component design for our use case including the message communication.
So we will end up with six components, each one covering it’s very own use case. Although the components can be arranged independently from each other using the Lightning App Builder they have clear defined dependencies to each other. This is because of the messages which needs to be exchanged between the single components. This means, in addition to the six components, we also need at least four different specific message channels. This also means that we can hardly reuse one of our components for another use case than the one we originally developed it for, because it relies on the specifically defined message communication with the other components.
Loose coupling and re-usage of components
It seems that to achieve a better re-usage of our components for different use case, we have to find a way to decouple the specific message communication from the actual implementation of our components. lwc-das does this by implementing the following pattern.
- Each component provides a set of outgoing properties, whose names can be set in the Lightning App Builder. The outgoing properties of all components included in the page form the distributed application state.
- Additionally, each component provides a set of dynamic incoming properties. The values of those properties, which can be set in the Lightning App Builder, can include properties of the distributed application state. The components automatically watch for changes in the distributed application state and update their dynamic properties, if necessary.
By implementing this pattern for our app the component design will change to the following.
The main differences are:
- We have reduced the number of used components to three.
- These three generic components (Object Data Table, Map and Record Details) are highly customizable via the App Builder and provide incoming and outgoing properties.
- Communication between these components happens automatically in the background just by configuring the incoming and outgoing properties.
At a first glance the message communication looks pretty chaotic. We are basically broadcasting each message to all of the other components. However, although the single components receive each state property change, they will just take care about the relevant ones.
After going through the theory let’s now have a look at how our app will be implemented using lwc-das.
The following illustration explains the property configuration for the communication between the account data table, the contact data table and the account location map in the Lightning App Builder
- We provide a name for the outgoing property of the account data table (selectedAccountIds)
- We use this property to filter the contact records in the contact data table.
- By using the same property on the location map component the account locations (billing address) will be displayed.
All it takes to get this working is to wrap a given component in a parent component which utilizes lwc-das and follow these steps:
You can find the complete example application in the lwc-das Github repository.
There’s even more
We covered the basics of lwc-das in this article. In the following articles we will see how to manipulate the global state and introduce new properties to make our application even more dynamic. Additionally, we will have a look at how to make components record context aware, to include them in a record page and make them deal with the record data.
At the moment the library just provides the foundation to build those kind of components and includes a few examples components like the ones we saw in this article. However, we plan to release several production ready components based on lwc-das over the next months.
Written by Oliver Preuschl, Technical Lead Architect at H+W CONSULT GmbH. Do you have any questions? Contact us