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, Lightning Component, Lightning Design System

Winter’18 Lightning Tree Component

Dev Shukla  and I had worked together on a lightning venture for a couple of months and We decided to start a blog series to share our learning and experiments with “Lightning Lovers”.Many thanks to Dev Shukla for his contributor to this blog series.You can connect with Dev at twitter and check more about him here.

Using lightning: tree To Display Leads with Activity Information

Winter’18 Salesforce has added a new lightning component called lightning:tree, using this we can display the hierarchy of Salesforce. lightning: tree component provides visualization of a structure hierarchy. Tree items, also known as branches, can be expanded or collapsed.This component supports only version 41.0 and above.
Winter18.png 620×378
Business Use Case: We can use this component for displaying the Hierarchy structure like Account Hierarchy, Role Hierarchy, Custom Object Hierarchy. Also, we can use this component to display the information in hierarchy level like Leads with Activity Information, Top customers with Top Deals information.
Here I created a sample component to display my Leads with respective Tasks and on click on respective Task it will display the Task important information in modal like Subject, Status, Assigned To, Due Date and comments.

Here is the working demo: Live Demo

Here you go step by step Instructions to create the Lightning tree component.

  1. Apex Controller


public class LightningTreeAuraController{
    
    @AuraEnabled
    public static List<item> getLeadTree(){
        
        List<item> items = new List<item>();
        List<Lead> leadList = new List<Lead>();
        //get list of leads and respective tasks
        leadList = [SELECT Id, Name, (SELECT Id, Subject From Tasks) From Lead LIMIT 10];
        for(Lead lead: leadList){
            
            //get task of current lead record
            List<item> taskItems = new List<item>();
            for(Task task: lead.Tasks){
                //add task items
                item taskItem = new item('Task :'+ task.Subject, String.valueOf(task.Id), false, null);
                taskItems.add(taskItem);
            }
            
            //add lead items
            item leadItem = new item('Lead :' +lead.Name, String.valueOf(lead.Id), false, taskItems);
            items.add(leadItem);
        }
        return items;
    }
    
    //Item Wrapper Class
    public class item{
        @AuraEnabled
        public String label {get; set;}
        @AuraEnabled
        public String name {get; set;}
        @AuraEnabled
        public Boolean expanded {get; set;}
        @AuraEnabled
        public List<item> items {get; set;}
        
        public item(String label, String name, Boolean expanded, List<item> items){
            this.label = label;
            this.name = name;
            this.expanded = expanded;
            this.items = items;
        }
    }
     //get task information based on Subject click
    @AuraEnabled
    public static Task getTaskDetails(Id recordId){
        Task task = [Select id,Subject,Owner.Name,Description,ActivityDate,Status from Task where Id=:recordId];
        return task;
        
    }

2.  Lightning Component code

1

You can take complete component code here

3.Lightning Component JS Controller Code

({
    doInit: function (component, event, helper) {
        helper.getLeadtree(component);
    },
    openModel: function(component,event, helper) {
        var TaskId = event.getParam('name');
        helper.getTaskDetails(component,TaskId);
    },

    closeModel: function(component, event, helper) {
        // for Hide/Close Model,set the "isOpen" attribute to "Fasle"
        component.set("v.isOpen", false);
    },
})

4. Lightning Component Helper code

({
    getLeadtree : function(component, event, helper) {
        var spinner = component.find("spnr");
        var action = component.get('c.getLeadTree');
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS'){
                //get lead and respective task list, and initialize with items
                component.set('v.items', response.getReturnValue());
                //hide spinner after getting data
                $A.util.toggleClass(spinner, "slds-hide");
            }else{
                $A.util.toggleClass(spinner, "slds-hide");
                alert('ERROR');
            }
        });
        $A.enqueueAction(action);

    },
    getTaskDetails : function(component, TaskId) {
        var action = component.get('c.getTaskDetails');

        action.setParams({
            recordId : TaskId
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            //get task information and initialize with task attribute
            component.set('v.task', response.getReturnValue());
            component.set("v.isOpen", true);

        });
        $A.enqueueAction(action);
    }
})

Here is Output of Component :

This slideshow requires JavaScript.

GitHub Repository
You can also download the code from the github repository here.

References :

Salesforce Documentation
Lightning Design System : Lightning Tree

lightning:tree to display Account Hierarchy