Posted in Lightning, Lightning Web Component, LWC, Salesforce

Lightning Web Component for AURA Developers Part – III

Call Apex Methods In Lightning web components

Let’s discuss here how to call the apex class from the Lightning web components. Lightning web components can import methods from Apex classes into the JavaScript classes using ES6 import.Before you use an Apex method, make sure that there isn’t an easier way to get the data. Before calling apex method first review a base Lightning component, like lightning-record-form, lightning-record-view-form, or lightning-record-edit-form works for your use case.

We can able to call the apex class in Lightning web component using these different ways.

For more information take a look here

Here some of highlights of this component.

  1. This component is used to display list of Accounts in picklist.
  2. The component is used to display list of Contacts related to respective Account. User can select Account Name from dropdown to see list of related contacts.

Here you go step by step Instructions to create the Lightning Web Component

Import Syntax

You can able use default export syntax to import an Apex method via the @salesforce/apex scoped module into JavaScript controller class. The Syntax looks like below.

import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod';
  • apexMethod—The imported symbol that identifies the Apex method.
  • Namespace—The namespace of the Salesforce organization. Specify a namespace unless the organization uses the default namespace (c), in which case don’t specify it.
  • Classname—The name of the Apex class.

To use @wire to call an Apex method, we must set cacheable=true. But once we have used cacheable we cannot use DML in that. If an Apex method is annotated with @AuraEnabled(cacheable=true), you can invoke it from a component via the @wirewire service.You can @wire a property if you just wanna use the response as it is.

Create Apex Class

In this example, we will be getting account data and show it into the UI. Create an apex class using SFDX create apex class command.

public class AccountLWCController {
     @AuraEnabled(cacheable=true)
    public static List<Account> getAccountList() {
        return [SELECT Id, Name FROM Account];
    }
    @AuraEnabled
    public static List<Contact> getContacts(String accountId){
        return [Select Id,FirstName,LastName,Email,Phone from Contact where accountId=:accountId];
        
    }  
}

Let’s build the AccountList LWC

Create a new Lightning web component using the below SFDX command
sfdx force:lightning:component:create --type lwc -n AccountList -d force-app/main/default/lwc

accountList.html

<template>
    <lightning-card >
        <div class="slds-page-header slds-page-header--object-home">
            <lightning-layout>
                <lightning-layout-item >
                    <lightning-icon icon-name="standard:contact" alternative-text="Contact" ></lightning-icon>
                </lightning-layout-item>
                <lightning-layout-item class="slds-m-left--small">
                    <p class="slds-text-title--caps slds-line-height--reset">Accounts</p>
                    <h1 class="slds-page-header__title slds-p-right--x-small">Contact
                        Viewer</h1>
                </lightning-layout-item>
            </lightning-layout>
            <lightning-layout >
                <lightning-layout-item >
                    <p class="slds-text-body--small"> Contacts • View
                        Contacts Based on Selected Account</p>
                </lightning-layout-item>
            </lightning-layout>
        </div>
        <label class="slds-form-element__label" for="select-01">Select Account</label>
        <div class="slds-form-element__control">
            <div class="slds-select_container">
                <select class="slds-select" id="select-01" onchange={onValueSelection}>
                    <!--iterate all picklist values from accounts list using for:each loop-->
                    <template for:each={accounts.data} for:item="acc">
                        <option key={acc.Id} value={acc.Id}>
                            {acc.Name}
                        </option>
                    </template>
                </select>
            </div>
        </div>
        <template if:true={contacts}>
            <lightning-card title="Contacts"  >
                <div style="height: 300px;">
                    <lightning-datatable
                                         key-field="Id"
                                         data={contacts}
                                         columns={columns}>
                    </lightning-datatable>
                </div>    
            </lightning-card>
        </template>
    </lightning-card>
</template>

accountList.js

The component’s JavaScript code imports the Apex method.On selection of picklist onValueSelection get triggered and call the getContacts() method with accountId parameter. Once getContacts() get called it gives the response as Promise and will handle that using .then() and .catch() properties.

import { LightningElement,wire,track } from 'lwc';

import getAccountList from '@salesforce/apex/AccountLWCController.getAccountList';
import getContacts from '@salesforce/apex/AccountLWCController.getContacts';

const columns = [{
        label: 'First Name',
        fieldName: 'FirstName'
    },
    {
        label: 'Last Name',
        fieldName: 'LastName'
    },
    {
        label: 'Email',
        fieldName: 'Email',
        type: 'email'
    },
    {
        label: 'Phone',
        fieldName: 'phone',
        type: 'phone'
    }

];
export default class AccountList extends LightningElement {
    @track accountId = '';
    @track contacts;
    @track columns = columns;
    //  invoke apex method with wire property and fetch picklist options.
    // pass 'object information' and 'picklist field API name' method params which we need to fetch from apex
    @wire(getAccountList) accounts;
    onValueSelection(event) {
        // eslint-disable-next-line no-alert
        const selectedAccount = event.target.value;
        this.accountId = event.target.value;
        if (selectedAccount != null) {
            getContacts({
                    accountId: selectedAccount
                })
                .then(result => {
                    this.contacts = result;
                    // eslint-disable-next-line no-console
                    console.log('result' + JSON.stringify(result) + selectedAccount);
                })
                .catch(error => {
                    this.error = error;
                });
        }
    }
} 

accountList.js-meta.xml

To make sure component is visible in Lightning App Builder you need to add targets and change isExposed to true in LightningDatatableExample.js-meta.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>47.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Account List</masterLabel>
  <description>This is a demo component.</description>
  <targets>
      <target>lightning__RecordPage</target>
      <target>lightning__AppPage</target>
      <target>lightning__HomePage</target>
  </targets>
</LightningComponentBundle>

Below is the output of component.

References:

Calling Apex class using LWC

Posted in Lightning Component, Lightning Web Component, LWC, Salesforce

Lightning Web Components for AURA Developers Part – II

The best way to compare the Aura Component and Lightning Web Components programming models is to look at code for similar components written in the two models. The goal of this post is to help you to leverage your Aura components skills to accelerate learning about Lightning web components. You learn how the two types of components work well together.

Prerequisites

Before you dive into this post, complete the Lightning Web Components Basics module, which gives you a great introduction to the new programming model.
I am assuming that you’re familiar with the Aura Components programming model, and we won’t explain its features, except in comparison to the Lightning Web Components programming model. If you’re not familiar with Aura components, start with the Aura Components Basics module.

Aura Initializers Become Lifecycle Hooks

Replace an init event handler in an Aura component with the standard JavaScript connectedCallback() method in a Lightning web component. The connectedCallback() lifecycle hook fires when a component is inserted into the DOM. Lifecycle hooks are callback methods that let you run code at each stage of a component’s lifecycle.We use the init event in an Aura component to initialize a component after component construction but before rendering.

Here’s an init event handler in the PropertyCarousel Aura component.

<aura:handler name="init" value="{!this}" action="{!c.onInit}"/>

The onInit function in the Aura component’s controller performs any necessary initialization.In a Lightning web component, use connectedCallback() instead in the component’s JavaScript file. Here’s an example inpropertySummary.js.

export default class PropertySummary extends LightningElement {
    ...
    connectedCallback() {
        // initialize component
    }
}

Migrate Base Components

This Aura component uses the lightning:formattedNumber base component.

<aura:component>
<lightning:formattedNumber value="5000" style="currency"
currencyCode="USD"/>
</aura:component>

To migrate this markup to a Lightning web component:

  • Change the colon that separates the namespace (lightning) and component name (formattedNumber) to a dash.
  • Change the camel-case component name (formattedNumber) to a dash-separated name (formatted-number).
  • Change the camel-case attribute name (currencyCode) to a dash-separated name (currency-code).

Here’s the equivalent Lightning web component.

<template>
    <lightning-formatted-number value="5000" style="currency"
      currency-code="USD" >
    </lightning-formatted-number>
</template>

Aura CSS Becomes Standard CSS

Lightning web components use standard CSS syntax. Remove the proprietary THIS class that Aura components use.
Here’s a portion of the CSS file for the PropertyTile Aura component.

.THIS .lower-third {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    color: #FFF;
    background-color: rgba(0, 0, 0, .3);
    padding: 6px 8px;
}

Similar CSS for the propertyTile Lightning web component uses standard CSS instead. The THIS keyword is specific to Aura and isn’t used in Lightning web components.

.lower-third {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    color: #FFF;
    background-color: rgba(0, 0, 0, .3);
    padding: 6px 8px;
}

Call Apex Methods

Here’s a portion of the js file for the calling apex method “getContacts” in Aura component.

var action = component.get("c.getContacts");
action.setCallback(this, function(data) {
    component.set("v.Contacts", data.getReturnValue());
});
$A.enqueueAction(action);

The JavaScript function calls the getContacts method of the Apex controller. It then populates the attribute named Contacts with the results.

Here’s a portion of the js file for the calling apex method “getContacts” in lightning web component.

import getContacts from '@salesforce/apex/ContactController.getContacts';

export default class ApexImperativeMethod extends LightningElement {
    @track contacts;
    @track error;

    handleLoad() {
        getContacts()
            .then(result => {
                this.contacts = result;
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                this.contacts = undefined;
            });
    }
}

Also don’t forget to review awesome Salesforce Lightning Web Component Cheat Sheet (Unofficial) prepared by @Santanu Boral

References:

Lightning Web Components for Aura Developers

Working with Aura and Lightning Web Components: Interoperability and Migration

Posted in Lightning Component, Lightning Web Component, LWC, Salesforce

Lightning Web Components for AURA Developers Part – I

The best way to compare the Aura Component and Lightning Web Components programming models is to look at code for similar components written in the two models. The goal of this post is to help you to leverage your Aura components skills to accelerate learning about Lightning web components. You learn how the two types of components work well together.

Prerequisites

Before you dive into this post, complete the Lightning Web Components Basics module, which gives you a great introduction to the new programming model.
I am assuming that you’re familiar with the Aura Components programming model, and we won’t explain its features, except in comparison to the Lightning Web Components programming model. If you’re not familiar with Aura components, start with the Aura Components Basics module.

Component Bundles

The component bundle file structure is different for an Aura component and a Lightning web component. Here’s how the files map between the two types of component.

(Source: Trailhead )

Migrate Markup

  • An Aura component contains markup in a .cmp file. The file starts with an <aura:component> tag and can contain HTML and Aura-specific tags.
  • A Lightning web component contains markup in a .html file. The file starts with a <template> tag and can contain HTML and directives for dynamic content.

Attributes Become JavaScript Properties

Migrate attributes from tags in the markup (.cmp) of an Aura component to JavaScript properties in the JavaScript file (.js) of a Lightning web component.

Aura component:

 <aura:attribute name="recordId" type="Id" />
 <aura:attribute name="account" type="Account" />

LWC :

import { LightningElement, api, track } from 'lwc';
export default class AccountSummary extends LightningElement {
    @api recordId;
    @track account;
        ...
}

The recordId and account attributes in the Aura component become the recordId and account JavaScript properties in the Lightning web component.

The two Lightning web component properties have different decorators. The @api and @track decorators both make a property reactive, which means that when the property value changes, the component’s HTML template rerenders.

The @api decorator marks recordId as a public reactive property. A public property is part of the public API for the component, which means that it can be set in Lightning App Builder, or by a parent component that uses the component in its markup.

The @track decorator marks property as a private reactive property, also known as a tracked property. These properties are used to track internal component state and aren’t part of the component’s public API.

Basic Aura Expressions Become HTML Expressions

Migrate basic expressions from markup in an Aura component to expressions in HTML in a Lightning web component. An example of a basic expression is a reference to an attribute in an Aura component.
For example, the AccountPaginator Aura component uses basic expressions to display the values of the page, pages, and total attributes.

<aura:component >
    <aura:attribute name="page" type="integer"/>
    <aura:attribute name="pages" type="integer"/>
    <aura:attribute name="total" type="integer"/>
    
    <div class="centered">{!v.total} Accounts • page {!v.page} of {!v.pages}</div>
</aura:component>

Here’s the equivalent syntax in the HTML file of the accountPaginator Lightning web component.

<template>
    {totalItemCount} items • page {currentPageNumber} of {totalPages}
</template>

The HTML references the totalItemCount property in paginator.js. The {currentPageNumber} and {totalPages} expressions reference getters that process the pageNumber and pageSize properties.

import { LightningElement, api } from 'lwc';
export default class Paginator extends LightningElement {
    /** The current page number. */
    @api pageNumber;
    /** The number of items on a page. */
    @api pageSize;
    /** The total number of items in the list. */
    @api totalItemCount;
    get currentPageNumber() {
        return this.totalItemCount === 0 ? 0 : this.pageNumber;
    }
    get totalPages() {
        return Math.ceil(this.totalItemCount / this.pageSize);
    }
}

Aura Conditionals Become HTML Conditionals

Migrate <aura:if> tags in an Aura component to if:true or if:false directives in a Lightning web component’s HTML file.
Here’s some conditional markup in the AccountDetails Aura component.

<aura:if isTrue="{!v.spinner}">
    <lightning:recordForm recordId="{!v.accountId}"
      objectApiName="Account"
      fields="{!v.accountFields}" columns="2"/>
</aura:if>

Here’s similar HTML in the accountDeatils Lightning web component.

<template if:true={spinner}>
    <lightning-record-form object-api-name="Account" 
      record-id={accountId} fields={accountFields} 
      columns="2">
    </lightning-record-form>
</template>

The HTML file of a Lightning web component starts with the standard HTML <template> tag, and it can also contain other <template> tags in its body. In this example, the content in the <template> tag conditionally renders depending on the result of the if:true directive.

Aura Iterations Become HTML Iterations

Migrate <aura:iteration> tags in an Aura component to for:each directives in a Lightning web component’s HTML file.
Here’s the Aura syntax in Sample.cmp.

<aura:iteration items="{!v.items}" itemVar="item">
    {!item}
</aura:iteration>

Here’s similar HTML in the sample Lightning web component.

<template for:each={items} for:item='item'>
    <p key={item.id}>{item}</p>
</template>

Stay tuned for next blog post for Lightning Web Components for AURA Developers Part- II.

References:

Lightning Web Components for Aura Developers

Working with Aura and Lightning Web Components: Interoperability and Migration

Posted in Lightning Web Component, LWC, Salesforce

Introducing New Lightning Web Components

Introducing Lightning Web Components

In case you missed it, Salesforce recently announced Lightning Web Components (LWCs) — a new programming model that developers can use in addition to the existing Aura-Based programming model to build Lightning components. 

Lightning Web Components is a new programming model for building Lightning components. It leverages the web standards breakthroughs of the last five years, can coexist and interoperate with the original Aura programming model, and delivers unparalleled performance.It’s not same as Lightning Components or built on top of Aura framework but it’s a different model which will co-exist with Lightning Components.
For more information Trailhead Project: Quick Start with Lightning Web Components

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML.

Lightning Web Component mainly consists of below mentioned files :

  • HTML provides the structure for your component.
  • JavaScript defines the core business logic and event handling.
  • CSS provides the look, feel, and animation for your component.
  • Component Configuration File(.js-meta.xml) –  This file provides metadata for Salesforce, including the design configuration for components intended for use in Lightning App Builder.

Here’s take a look simple Lightning web component that displays “Hello World” in an input field.

HTML

<template>
    <input value={message}></input>
</template>

JavaScript

import { LightningElement } from 'lwc';
export default class App extends LightningElement {   
message = 'Hello World'; 
}

CSS

input {
   color: blue;
}

Component Configuration File

<?xml version=”1.0″ encoding=”UTF-8″?>
<LightningComponentBundle xmlns=”http://soap.sforce.com/2006/04/metadata” fqn=”helloWorld”>
<apiVersion>45.0</apiVersion>
<isExposed>true </isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
<targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
            </objects>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>
  • Required
    • apiVersion binds the component to a Salesforce API version.
    • isExposed (true or false) makes the component available from other namespaces. Only set this to true to make a component usable in a managed package or by Lightning App Builder in another org.
  • Optional
    • targets specify which types of Lightning pages the component can be added to in the Lightning App Builder.
    • targetConfigs let you specify behavior specific to each type of Lightning page, including things like which objects support the component.

See the documentation for the full list of supported syntax.

Decorators

The Lightning Web Components programming model has three decorators that add functionality to a property or function.
The ability to create decorators is part of ECMAScript, but these three decorators are unique to Lightning Web Components.

@api
To expose a public property, decorate it with @api. Public properties define the API for a component. An owner component that uses the component in its markup can access the component’s public properties. Public properties are reactive. If the value of a reactive property changes, the component’s template rerenders any content that references the property.
See Public Properties.
To expose a public method, decorate it with @api. Public methods are part of a component’s API. To communicate down the containment hierarchy, owner and parent components can call JavaScript methods on child components.
See Public Methods.
@track
To track a private property’s value and rerender a component when it changes, decorate the property with @track. Tracked properties are also called private reactive properties.
See Tracked Properties.
@wire
To read Salesforce data, Lightning web components use a reactive wire service. When the wire service provisions data, the component rerenders. Components use @wire in their JavaScript class to specify a wire adaptor or an Apex method.
See Use the Wire Service to Get Data and Call Apex Methods

What happens to Lightning Components?

Lightning Components are not going away and they will continue to exist in parallel to Lightning Web Components. It’s something similar when Lightning Components were available and we started thinking that if it’s going to replace Visualforce pages.
As VF pages and Lightning Components co-existed, now they are being joined with Lightning Web Components. It will be more of a choice of the framework that you will want to choose when building UI components. With the standard Web development model, it looks like Lightning Web Components definitely will be the choice in future.

Migration Strategy

The programming model for Lightning Web Components is fundamentally different than the model for Aura Components. Migrating an Aura component to a Lightning web component is not a line-by-line conversion, and it’s a good opportunity to revisit your component’s design. Before you migrate an Aura component, evaluate the component’s attributes, interfaces, structures, patterns, and data flow.

To understand more about migration strategy stay tuned for my next blog posts where i will explain in details about Lightning Web Components for AURA Developers.

Lightning Web Components for AURA Developers Part – I

References :

Lightning Web Components Basics

Introducing Lightning Web Components

Lightning Web Components ( LWC ) in Salesforce with Non-Scratch Org