Exploring Salesforce Lightning Web Components: Part 4

Focusing on some JavaScript specifics.

Image for post
Image for post

This article is part of the series starting with Exploring Salesforce Lightning Web Components: Part 1.

Common Code

So far, our JavaScript has been constrained to be within a single Lighting Web Component file (module), e.g., helloWorld.js. Say now, however, we have two Lighting Web Components that have some common code between them; how can we share this common code?

The answer is to create another Lighting Web Component whose JavaScript file (module) exports values, e.g. functions.

As a concrete example, we create a new Lighting Web Component called common. We delete the component’s HTML file and update the JavaScript file to the following straightforward implementation:

We now update the helloWorld component’s JavaScript to use the exported functions.

To illustrate code sharing, one can create a duplicate helloWorld2 component.

Observations:

  • The import statement uses an unusual syntax, unique to Lighting Web Components, where we prepend the c/ to refer to another component’s JavaScript file
  • As one types into the input, triggering the changeHander function, one will observe an incrementing value being displayed on the console
  • One super important observation is that as one types text into either of the helloWorld or helloWorld component inputs, the same value is updated between them. Specifically, the common Lighting Web Component’s JavaScript is instantiated as a single JavaScript module; follows a singleton pattern

note: While we will later explore other more standard ways to facilitate inter-component communication, we could achieve much the same effect by taking advantage of the singleton pattern in common code.

External Scripts

Now that we see Lightning Web Components as a mechanism to easily and safely create custom features in Salesforce, we explore how to power this customization with third-party JavaScript libraries.

One security limitation, however, is that Lightning Web Components must abide to a strict Content Security Policy configuration:

— Salesforce — Content Security Policy Overview

One CSP policy is that all scripts must be loaded from the same domain and as such we need to serve them from the Salesforce org. To accomplish this, we store the scripts in the project’s staticresources folder, load them at run-time, and access their features off the component’s local window object. Let illustrate this with a simple example that simply sets a property on the window object.

We create a file; force-app/main/default/staticresources/hello.js:

In the same folder, we create a meta file; hello.resource-meta.xml:

And we update the Lightning Web Component’s JavaScript to load this script at run time.

Observations:

  • The hello import is simply the URL to the script
  • Unlike the other imports, e.g., LightningElement, which are available at compile time, this script is available at run time
  • The script sets a property on a window object and the component reads that property
  • Similar to code within a Lighting Web Component, loaded scripts do not have access to the global window object; each has access to only a local component window object. Thus, unlike the common code module example, code in external scripts cannot be used to facilitate inter-component communication

Another interesting observation is that one cannot use npm to install compile time third-party dependencies in a component’s folder; I tried and found that the Lightning Web Component build system would fail to deploy the project in this case.

Directly Manipulating the DOM

While Lighting Web Component manages its DOM, it provides an escape hatch to allow one to directly manipulate a portion of that DOM. To illustrate this feature, we will use the d3 library to create a rudimentary bar chart.

Image for post
Image for post

note: While it is not important to understand d3 for the purposes of this article, the following article is an excellent introduction to it: Enter, Update, Exit.

We first create the DOM element that we will directly manipulate:

Observations:

  • The key here is using the directive lwc:dom=”manual”
  • It is also important to use a class versus and id to identify the DOM element; this is a subtle requirement of Lighting Web Components (buried in their documentation)

We supply a bit of CSS:

And finally, we update the JavaScript:

Observations:

  • First, we use the component’s renderedCallback method to wait for the component to have rendered the DOM
  • We use the template property to get a reference to the component’s document object; where use the standard querySelector method to get a reference to the chart element
  • Finally, we supply the chart element to updateChart method to work d3 magic on it

A Side Bar into React

Going into writing this series, I went in with the assumption that I was going to rely on the fact that Lighting Web Components are Web Components under the hood to end up using React (my preferred JavaScript framework) to develop custom Salesforce UI functionality.

The following article explains how React and Web Components can be used together: Web Components by Example: Part 6.

While I successfully got this approach to work with Lightning Web Components, here are some observations:

  • First, since you cannot use npm to import third-party compile time external libraries, I had to develop the React application outside of the Salesforce development environment and bring in the final JavaScript bundle; a clumsy development workflow
  • There is some trickiness in using React with Web Components, e.g., one cannot easily (or at all) use Create React App. Rather one needs to use a custom webpack configuration
  • In learning Lightning Web Components, I am learning that many of the patterns that I like with React are equally applicable to Lightning Web Components

With all this in mind, I am warming up to the idea of developing custom Salesforce UI using Lighting Web Components using out-of-the-box’s functionality.

Next Steps

So far we have been focused on creating a Lightning Web Component. in the coming articles, starting with Exploring Salesforce Lightning Web Components: Part 5, we will explore how to combine them into a more complication application.

Written by

Broad infrastructure, development, and soft-skill background

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store