Lightning Web Components Basics

Discover Lightning Web Components

Explain the Lightning Web Components programming model. List the benefits of using Lightning web components. Find what you need to get started developing Lightning web components.
  • An Open Door to Programming with Web Standards
    • Programming with Web Standards - standard technologies like HTML, JavaScript, and CSS are used to build the next generation of Salesforce apps while maintaining compatibility with existing Aura components.
      • LWC opens to door to existing technologies
    • Capitalization convention Salesforce uses:
      • Programming model: “Lightning Web Components”
      • Components themselves: “Lightning web components”
  • Before You Go Further
  • Why Lightning Web Components?
    • Modern browsers are based on web standards that are constantly improving what browsers can present to a user
    • Since LWC is build on code that runs natively in browsers, LWC is lightweight and performant
    • Its easier to find solutions to common places on the web, find developers with necessary skills/experience, develop faster, use full encapsulation so components are more versatile
    • Browsers have been creating web components for years: select, video, input - any tags that serve as more than a container
  • Simple Component Creation
    • Simply create components using HTML, JavaScript, and (optionally) CSS:
      • HTML: Provides structure for your component
      • JavaScript: Defines the core business logic and event handling
      • CSS: Provides the look, feel, and animation for your component
    • At a minimum, you just need an HTML file and a Javascript file with the same name in the same folder, also with the same name
      • Deploy those to an org with some metadata and Salesforce compiles the files and takes care of the component construction automatically

HTML

  • template tag is a fundamental building block of component’s HMTL - it allows you to store pieces of HTML
<template>
    <input value={message}></input>
</template>

JavaScript

  • Import statements and class declarations covered below.
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
  message = 'Hello World';
}

CSS

  • At a minimum only HTML and JavaScript files are needed
input {
   color: blue;
}

https://app.lwc.studio/ (previously https://webcomponents.dev/create/lwc)

  • The header is a link that lets us try out components, change them, and see immediate results
    • You can use GitHub to log in to WebComponents.dev
    • “Stories” tab at webcomponents.dev shows the output

  • Lightning Web Components and Aura Components Do Work Together
    • Over time, Aura components are likely to migrate to the Lightning Web Component model, but in the meantime both are supported.
    • Aura components can contain Lightning web components, but not vice versa
    • A pure Lightning web components implementation provides full encapsulation and evolving adherence to common standards

  • References and Resources
    • Salesforce DX tool set
      • Scratch Orgs: disposable Salesforce orgs to support development and testing
      • Dev Hubs: feature that manages scratch orgs
      • Salesforce Command Line Interface (CLI): provides a quick way to run operations for creating and configuring scratch orgs and deploying components
      • Lightning Component Library:
    • GitHub: extensions, samples, etc are available through GitHub repos
      • Visual Studio Code Salesforce Extension Pack: provides code-hinting, lint warnings, built-in commands
      • LWC Recipes: provides a GitHub repo to help you see how web components work
      • E-Bikes Demo: end-to-end implementation of Lightning web components to create an app. Can deploy in your own Trailhead Playground
      • Lightning Data Service (LDS): access data and metadata from Salesforce. Base Lightning components that work with data are built on LDS
      • Lightning Locker: Lightning Locker secures components from one namespace from components in another namespace

  • A Lightning web component requires the following files: HTML, JS
  • An IDE, like WebComponents.dev, lets you: try your component files in a simulated environment

    The following images were taken from a Salesforce blog post introducing LWCs located here.

2014 web stack

2019 web stack

Lightning Web Components

Lightning Web Components versus Aura Components

Create Lightning Web Components

Describe the contents of each component file. Create JavaScript methods for a Lightning web component. Use Lifecycle Hooks in component JavaScript.
  • A component simply needs a folder and its file with the same name - they’re auto-linked by name and location

  • productCard Component in eBikes Sample Repo
    • Linked above an example of a data display element - the following breaks down the structure of the files that form the LWC
    • All LWCs have a namespace that’s separated from the folder name by a hyphen. Ex: markup for the LWC component with the folder name app in the default namespace c is <c-app>
    • But, Salesforce platform doesn’t allow hyphens in the component folder or file names, so mycomponent cannot be named my-component. Instead, we use camel case to name it myComponent
      • camelCase component folder names map to kebab-case in markup.
      • In markup, to reference aa component with folder name myComponent, use <c-my-component>
  • Example 1: HTML/Javascript Files
    • Lightning web component HTML files all include the template tag - these contain the HTML that defines the structure of your component
    • View examples below by copying/pasting into the appropriate files at webcomponents.dev/create/lwc
    • Identifiers in the curly brace {} are bound to the fields of the same name in correspondning JavaScript class

HTML File

<template>
    <div>
        <div>Name: {name}</div>
        <div>Description: {description}</div>
        <div>Category: {category}</div>
        <div>Material: {material}</div>
        <div>Price: {price}</div>
        <div><img src={pictureUrl}/></div>
    </div>
</template>

JavaScript File

import { LightningElement } from 'lwc';
export default class App extends LightningElement {
   name = 'Electra X4';
   description = 'A sweet bike built for comfort.';
   category = 'Mountain';
   material = 'Steel';
   price = '$2,700';
   pictureUrl = 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg';
}

  • Example 2: HTML/Javascript Files
    • Real world example - you want to display data, but it can take time to load. Can use conditional directives within the template to determine which visual elements are rendered.

HTML File

<template>
    <div id="waiting" if:false={ready}>Loading…</div>
    <div id="display" if:true={ready}>
        <div>Name: {name}</div>
        <div>Description: {description}</div>
        <div>Category: {category}</div>
        <div>Material: {material}</div>
        <div>Price: {price}</div>
        <div><img src={pictureUrl}/></div>
    </div>
</template>

JavaScript File

import { LightningElement } from 'lwc';
export default class App extends LightningElement {
   name = 'Electra X4';
   description = 'A sweet bike built for comfort.';
   category = 'Mountain';
   material = 'Steel';
   price = '$2,700';
   pictureUrl = 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg';
   ready = false;
   connectedCallback() {
       setTimeout(() => {
           this.ready = true;
       }, 3000);
   }
}

  • Base Lightning Web Components
    • Generally you don’t want to build all your components ground up - instead you can use a base Lightning web component.
      • Example components: field types, display controllers, navigation items, etc
    • Replace the div tags for material and category with a lightning-badge component:
<template>
    <div id="waiting" if:false={ready}>Loading…</div>
    <div id="display" if:true={ready}>
        <div>Name: {name}</div>
        <div>Description: {description}</div>
        <lightning-badge label={material}></lightning-badge>
        <lightning-badge label={category}></lightning-badge>
        <div>Price: {price}</div>
        <div><img src={pictureUrl}/></div>
    </div>
</template>
  • Working with JavaScript
    • JavaScript methods define what to do with input, data, events, changes to state, etc, to make your component work
    • export statement below defines a class that extends the LightningElement class
    • JavaScript file must included at least the following code, where MyComponent is the name you assign the component class
import { LightningElement } from 'lwc';
export default class MyComponent extends LightningElement {
}
  • The LWC Module
    • Lightning Web Components uses modules to build functionality and make it accessible to JavaScript in your component file.
      • Core module is lwc
      • LightningElement is base class for LWCs, which allows us to use connectedCallback()
      • connectedCallback() is a “lifecycle hook.” This method is triggered when a component is inserted in the document object model (DOM).
// import module elements
import { LightningElement} from 'lwc';
// declare class to expose the component
export default class App extends LightningElement {
    ready = false;
    // use lifecycle hook
    connectedCallback() {
        setTimeout(() => {
            this.ready = true;
        }, 3000);
    }
}
  • Lifecycle Hooks provide a means of “hooking” your code up to critical events in a component’s lifecycle.
    • Component lifecycle includes when a component is:
      • Created
      • Added to the DOM - connectedCallback()
      • Rendered in the browser
      • Encountering errors
      • Removed from the DOM - disconnectedCallback()
    • Note that the this keyword was used - it refers to the top level of the current context. Above, this context is the class.
  • Decorators - used in JavaScript to modify the behavior of a property/function
    • Need to be imported from the lwc module. Examples:
      • @api: marks a field/property as public. Public properties are reactive - the framework observes the property for changes.
      • @track: tells the framework to observe changes to properties of an object or elements of an array.
      • @wire: gives you an easy way to get and bind data from a Salesforce org.
import { LightningElement, api } from 'lwc';
export default class MyComponent extends LightningElement{
    @api message;
}
  • Example 3: HTML/JavaScript with Decorators
    • Following example uses the @api decorator to render a value from one component (bike) in another component (app)

“App” component HTML

<!-- app.html -->
<template>
<div>
    <c-bike bike={bike}></c-bike>
</div>
</template>

“App” component JavaScript

// app.js
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
    bike = {
        name: 'Electra X4',
        picture: 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg'
    };
}

“Bike” component HTML

<!-- bike.html -->
<template>
    <img src={bike.picture} alt="bike picture" />
    <p>{bike.name}</p>
</template>

“Bike” component JavaScript

// bike.js
import { LightningElement, api } from 'lwc';
export default class Bike extends LightningElement {
    @api bike;
}

Deploy Lightning Web Component Files

Configure Lightning web component files for display in an org. Deploy your files to an org. Verify component behavior in an org environment.
  • Steps to Create an LWC
    1. Create a project via SFDX: Create Project from VS Code
    2. Right-click the lwc folder and select SFDX: Create Lightning Web Component
    3. For this example, name the component LWC, and accept the default location
    4. Connect Visual Studio to Trailhead by authorizing an org with command SFDX: Authorize an Org in Visual Studio
    5. Edit the boilerplate bikeCard.html, bikeCard.js, and bikeCard.js-meta.xml files with the following:

bikeCard.html

<template>
    <div>
        <div>Name: {name}</div>
        <div>Description: {description}</div>
        <lightning-badge label={material}></lightning-badge>
        <lightning-badge label={category}></lightning-badge>
        <div>Price: {price}</div>
        <div><img src={pictureUrl}/></div>
    </div>
</template>

bikeCard.js

import { LightningElement } from 'lwc';
export default class BikeCard extends LightningElement {
   name = 'Electra X4';
   description = 'A sweet bike built for comfort.';
   category = 'Mountain';
   material = 'Steel';
   price = '$2,700';
   pictureUrl = 'https://s3-us-west-1.amazonaws.com/sfdc-demo/ebikes/electrax4.jpg';
 }

bikeCard.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <!-- The apiVersion may need to be increased for the current release -->
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Product Card</masterLabel>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

The Component Configuration File

  • js-meta.xml file - provides metadata for Salesforce, including the design configuration for components intended for use in Lightning App Builder
    • apiVersion is required, and binds the component to a Salesforce API version
    • isExposed (true or false) is optional, makes the component available from other namespaces. Only set to true to make a Lightning component usable in these cases:
      • From a managed package in Aura
      • From a Lightning App Builder in another org
    • targets is optional, and specifies which types of Lightning pages the component can be added to in the Lightning App Builder
    • targetConfigs is optional, and lets you specify behavior specific to each type of Lightning page, including things like which objects support the component
    • Reference these documents for full list of syntax

Example from ebikes repo:

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Product Card</masterLabel>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Product__c</object>
            </objects>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

Displaying a Component in an Org

  • 2 options for displaying a component:
    1. Set the component to support flexipage types (home, record home, etc)
    2. Create a tab pointing to an Aura component containing the LWC

Deploy Your Files

  • Authenticate with your Dev Hub org using SFDX: Authorize an Org
  • Deploy the project files using SFDX: Deploy this Source to Org

Create a New Page for Your Component

  • Setup > Quick Find > Lightning App Builder > New > App Page > One Region
  • Drag the component “Product Card” onto the page

Handle Events in Lightning Web Components

Create an app that includes multiple components. Describe the file structure of a complex component. Handle events.
  • Follow an Event’s Journey
    • Sample app discussed below has four components working together:
      1. Tile: displays an individual item
      2. List: arranges the tiles
      3. Detail: displays item details when clicked
      4. Selector: contains the whole set of components
  • Component Composition
    • Several zipped up files and folders are provided on the trailhead, shown below (data, detail, list, selector, tile)

  • Component Relationships
    • In the app, multiple components work together - some components are nested inside other components - Lightning web components can nest inside one another just like HTML elements can nest inside one another

selector.html: lays out the page and renders the list (c-list) and detail (c-detail) components

<template>
    <div class="wrapper">
    <header class="header">Select a Bike</header>
    <section class="content">
        <div class="columns">
        <main class="main" >
            <c-list onproductselected={handleProductSelected}></c-list>
        </main>
        <aside class="sidebar-second">
            <c-detail product-id={selectedProductId}></c-detail>
        </aside>
        </div>
    </section>
    </div>
</template>

detail.html: conditional rendering (if:true={product} and if:false={product})

<template>
    <template if:true={product}>
        <div class="container">
            <div>{product.fields.Name.value}</div>
            <div class="price">{product.fields.MSRP__c.displayValue}</div>
            <div class="description">{product.fields.Description__c.value}</div>
            <img class="product-img" src={product.fields.Picture_URL__c.value}></img>
            <p>
                <lightning-badge label={product.fields.Material__c.value}></lightning-badge>
                <lightning-badge label={product.fields.Level__c.value}></lightning-badge>
            </p>
            <p>
                <lightning-badge label={product.fields.Category__c.value}></lightning-badge>
            </p>
        </div>
    </template>
    <template if:false={product}>
        <div>Select a bike</div>
    </template>
</template>

list.html: renders several tile (c-tile) components, one for each bike

<template>
    <div class="container">
        <template for:each={bikes} for:item="bike">
            <c-tile>
                key={bike.fields.Id.value} 
                product={bike} 
                ontileclick={handleTileClick}>
            </c-tile>
        </template>
    </div>
</template>

list.css: specifies styling of the tiles

.container {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
}
  • Events Up, Properties Down
    • In complex components (that contain several parents and children) the components communicate up and down
      1. c-todo-item child component dispatches an event to the parent c-todo-app component
        • Child passes an event object to the parent when a user clicks a button so the parent can handle the event and change the current page
      2. c-todo-app parent component passes a property or invokes a method in the c-todo-item component
        • Parent can set a text value in a child component, or invoke a method in the child component

  • Passing Information Up
    • Info is passed up using events and event listeners
    • Child component dispatches the event and the parent listens for it
      • Ex: child component like this one contains a nextHandler() method that creates a simple event object using customEvent(), dispatching the event type ‘next’ when the user clicks a Next button
        • Event types can be any string but should conform to the DOM event standard of no uppercase letters, no spaces, and underscores to separate words

todoItem.js:

import { LightningElement } from 'lwc';
...
    nextHandler() {
        this.dispatchEvent(new CustomEvent('next'));
    }
}

todoApp.html: parent listens for the event with the inline event handler prefixed with on (onnext)

<template>
    <c-todo-item onnext={nextHandler}></c-todo-item>
</template>

todoApp.js: and passes the event object to an event handler

import { LightningElement } from 'lwc';
export default class TodoApp extends LightningElement {
...
nextHandler(){
        this.page = this.page + 1;
    }
}
  • Passing Information Down
    • Info can be passed down using public properties and public methods
    • Example 1: Public Properties
      • Make a component property public by prefacing it with @api decorator, then set the public property by an external component
      • Note: property names in JavaScript are in camel case while HTML attribute names are in kebab case (dash-separated) to match HTML standards
      • Public properties are good for passing down primitive values, simple objects, and arrays

todoItem.js: c-todo-item child component

import { LightningElement, api } from 'lwc';
export default class TodoItem extends LightningElement {
   @api itemName;
}

todoApp.html: set value from the parent

<template>
    <c-todo-item item-name="Milk"></c-todo-item>
</template>
  • Example 2: Public Properties
    • Use getters and setters to execute logic when properties are get or set - annotate them with the @api decorator to make them public for other components

videoPlayer.js: child component

import { LightningElement, api } from 'lwc';
export default class VideoPlayer extends LightningElement {
   @api
   play() {
       // Play music!
   }
}

methodCaller.js: when c-video-player component is included in a parent, invoke the method from the parent like this:

  • handlePlay() was defined and fires the event
  • querySelector() DOM method is used to search for a DOM element called c-video-player and invoke its public method
import { LightningElement } from 'lwc';
export default class MethodCaller extends LightningElement {
   handlePlay() {
      this.template.querySelector('c-video-player').play();
   }
}
  • Handling Events in HTML
    • Imagine the selector app needs to handle one type of event - user clicking a tile. Two options:
      • Handle events in HTML: add an event listener in the template (HTML is recommended)
      • JavaScript: write an event listener function (not recommended)

tile.html: each tile component listens for the user click because the tile component contains an onclick event listener

<template>
    <div class="container">
        <a onclick={tileClick}>
            <div class="title">{product.fields.Name.value}</div>
            <img class="product-img" src={product.fields.Picture_URL__c.value}></img>
        </a>
    </div>
</template>

tile.js: onclick listener calls the handler function tileClick in the tile.js JavaScript file

import { LightningElement, api } from 'lwc';
export default class Tile extends LightningElement {
    @api product;
    tileClick() {
        const event = new CustomEvent('tileclick', {
            // detail contains only primitives
            detail: this.product.fields.Id.value
        });
        // Fire the event from c-tile
        this.dispatchEvent(event);
    }
}
  • Selector App Event Pattern
    • The product selector app demoed on Salesforce is a complex component (one with several parent and child components)
      • Salesforce recommends propagating the event up through the component hierarchy, so parent components can respond to child events
      • If you have other child components (aside from the one firing the event), you can pass a property down to those children in response
      • To accomplish this, you need to chain event listeners and handlers up the hierarchy to the ebikes component, then pass a property down to the detail component - see the pattern below

  1. tile.html has onclick event listener that calls tileClick handler
<template>
    <div class="container">
        <a onclick={tileClick}>
            <div class="title">{product.fields.Name.value}</div>
            <img class="product-img" src={product.fields.Picture_URL__c.value}></img>
        </a>
    </div>
</template>
  1. tile.js has tileClick method that creates a new CustomEvent with type tileClick and an object containing a detail value (this.product.fields.Id.value)
import { LightningElement, api } from 'lwc';

export default class Tile extends LightningElement {
    @api product;

    tileClick() {
        const event = new CustomEvent('tileclick', {
            // detail contains only primitives
            detail: this.product.fields.Id.value
        });
        // Fire the event from c-tile
        this.dispatchEvent(event);
    }
}
  1. list.html has ontileclick listener that calls the handleTileClick handler
<template>
    <div class="container">
        <template for:each={bikes} for:item="bike">
            <c-tile>
                key={bike.fields.Id.value} 
                product={bike} 
                ontileclick={handleTileClick}>
            </c-tile>
        </template>
    </div>
</template>
  1. list.js has the handleTileClick method that passes in the event (evt) to create another CustomEvent (productselected) with an object also containing a detail value evt.detail. It dispatches the event in JavaScript.
import { LightningElement } from 'lwc';
import { bikes } from 'c/data';

export default class List extends LightningElement {
    bikes = bikes;

    handleTileClick(evt) {
        // This component wants to emit a productselected event to its parent
        const event = new CustomEvent('productselected', {
            detail: evt.detail
        });
        // Fire the event from c-list
        this.dispatchEvent(event);
    }
}
  1. selector.html has the onproductselected event listener that calls the handleProductSelected handler
<template>
    <div class="wrapper">
    <header class="header">Select a Bike</header>
    <section class="content">
        <div class="columns">
        <main class="main" >
            <c-list onproductselected={handleProductSelected}></c-list>
        </main>
        <aside class="sidebar-second">
            <c-detail product-id={selectedProductId}></c-detail>
        </aside>
        </div>
    </section>
    </div>
</template>
  1. selector.js has the handleProductSelected method set selectedProductId to the evt.detail value that was passed into it
import { LightningElement } from 'lwc';

export default class Selector extends LightningElement {
    selectedProductId;

    handleProductSelected(evt) {
        this.selectedProductId = evt.detail;
    }
}

  1. detail.html has a conditional directive waiting for a product value
<template>
    <template if:true={product}>
        <div class="container">
            <div>{product.fields.Name.value}</div>
            <div class="price">{product.fields.MSRP__c.displayValue}</div>
            <div class="description">{product.fields.Description__c.value}</div>
            <img class="product-img" src={product.fields.Picture_URL__c.value}></img>
            <p>
                <lightning-badge label={product.fields.Material__c.value}></lightning-badge>
                <lightning-badge label={product.fields.Level__c.value}></lightning-badge>
            </p>
            <p>
                <lightning-badge label={product.fields.Category__c.value}></lightning-badge>
            </p>
        </div>
    </template>
    <template if:false={product}>
        <div>Select a bike</div>
    </template>
</template>
  1. detail.js brings the pieces together, creating a private variable productId to track the state of the productId value. Then it uses a get/set pattern to get the value and set it to a variable product which lets detail.html load the conditional content
import { LightningElement, api } from 'lwc';
import { bikes } from 'c/data';


export default class Detail extends LightningElement {

    // Ensure changes are reactive when product is updated
    product;

    // Private var to track @api productId
    _productId = undefined;

    // Use set and get to process the value every time it's
    // requested while switching between products
    set productId(value) {
        this._productId = value;
        this.product = bikes.find(bike => bike.fields.Id.value === value);
    }
    
    // getter for productId
    @api get productId(){
        return this._productId;
    }
}

  • Deploy Your Files to Your Org
    • Right click the default folder and select SFDX: Deploy Source to Org to move the source code to the org

  • The following nests one component inside another: <c-detail product-id={selectedProductId}></c-detail>
  • The following describes an event handling pattern in a complex component app: Events are dispatched up from child to parent, then properties are passed down from parent to child

Add Styles and Data to a Lightning Web Component

Use CSS and Lightning Design System with a component. Get data from a Salesforce org. Deploy your app to an org and test it.
  • Adapt Your Component
    • This unit demos how to control a component’s appearance and pull in live data from Salesforce
  • CSS and Component Styling
    • CSS for Lightning Web Components adheres to W3C standard - its automatically applied to the corresponding HTML file
    • “Shadow DOM” is a mechanism that allows Lightning Web Components to encapsulate components, keeping them separate from the global DOM

detail.css: after adding the following, compare it to the detail section above

body{
  margin: 0;
}
.price {
  color: green;
  font-weight: bold;
}

  • Applying Lightning Design System Styles
    • Salesforce Lightning Design System (SLDS) is a CSS framework that provides a look and feel consistent with Lightning Experience
    • Following code snippet updates detail.html file to use slds-text-heading_small and slds-text-heading_medium fot settings - see result below
<template>
    <template if:true={product}>
    <div class="container">
        <div class="slds-text-heading_small">{product.fields.Name.value}</div>
        <div class="price">{product.fields.MSRP__c.displayValue}</div>
        <div class="description">{product.fields.Description__c.value}</div>
        <img class="product-img" src={product.fields.Picture_URL__c.value}></img>
        <p>
            <lightning-badge label={product.fields.Material__c.value}></lightning-badge>
            <lightning-badge label={product.fields.Level__c.value}></lightning-badge>
        </p>
        <p>
            <lightning-badge label={product.fields.Category__c.value}></lightning-badge>
        </p>
    </div>
    </template>
    <template if:false={product}>
    <div class="slds-text-heading_medium">Select a bike</div>
    </template>
</template>

  • Get Salesforce Data
    • Lightning Web Components use a reactive wire service which is build on Lightning Data Service
  • The Wire Service Brings Data to Your App
    • @wire decorator implements the wire service for your app - to use it:
      1. Import a wire adapter in the JavaScript file
      2. Decorate a property or function with the @wire decorator
    • The syntax follows:
      • adapterId: Identifier, identifier of the wire adapter
      • adapter-module: String, identifier of the module that contains the wire adapter function
      • adapterConfig: Object, a configuration object specific to the wire adapter
      • propertyOrFunction: private property or function that receives the stream of data from the wire service.
        • If a property is decorated with @wire the results are returned to the property’s data or error property
        • If a function is decorated with @wire, the results are returned in an object with a data property and an error property

General Syntax:

import { adapterId } from 'adapter-module';
@wire(adapterId, adapterConfig)
propertyOrFunction;

selector.js:

  • Line 1 imports the wire service from lwc
  • Line 2 imports the adapterId and adapter-modules for getRecord and getFieldValue from lightning/uiRecordApi
  • Line 3 imports the current User Id using the @salesforce module
  • Line 4 imports the @salesforce scheme for User.Name
  • Line 12 uses the @wire decorator to use the wire service to call getRecord passing in the userId and getting the fields
  • Line 13 sets user as the receiver for the @wire call
import { LightningElement, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import Id from '@salesforce/user/Id';
import NAME_FIELD from '@salesforce/schema/User.Name';
const fields = [NAME_FIELD];
export default class Selector extends LightningElement {
    selectedProductId;
    handleProductSelected(evt) {
        this.selectedProductId = evt.detail;
    }
    userId = Id;
    @wire(getRecord, { recordId: '$userId', fields })
    user;
    get name() {
        return getFieldValue(this.user.data, NAME_FIELD);
    }
}

selector.html: edited to include the name

<template>
    <div class="wrapper">
    <header class="header">Available Bikes for {name}</header>
    <section class="content">
        <div class="columns">
        <main class="main" >
            <c-list onproductselected={handleProductSelected}></c-list>
        </main>
        <aside class="sidebar-second">
            <c-detail product-id={selectedProductId}></c-detail>
        </aside>
        </div>
    </section>
    </div>
</template>

  • Mobile-Friendly Markup
    • Salesforce recommends designing for mobile first, using Salesforce’s mobile preview tools, then designing for desktop

More Resources: