Showing posts with label Lighning Web Component. Show all posts
Showing posts with label Lighning Web Component. Show all posts

Thursday, 28 March 2019

Lightning Web Components Best practices


We did one live session on Lightning Web Components (LWC) best practices with "René Winkelmeyer" in ApexHours. In that session we talk about how to build rich, efficient, and resilient Lightning Web Components. That webinar covered best practices around
  1. Using public, and private properties for effective component composition.
    1. When we should use @api or @track variable
  2. Event communication for child-to-parent as well as for sibling components (pubsub).
    1. Parent to Child Communication
    2. Child to Parent Communication
    3.  pubsub
  3. When, and when not, to use Apex with Lightning Web Components
    1. UI Record Api in LWC
    2. Lightning Data Service in LWC (Lightning record form)
  4. Aura interoperabilitys Recipes, Patterns and Best Practices
  5. How to debug Lightning Web Components
  6. How to test Lightning Web Component (Lightning Testing Service)
    1. Jest Tests for Lightning Web Components ( LTS )
       
Here is some best practice :-

1) LWC component Bundle naming convention 

 Check this post to learn about what is camelCase, PascalCase and kebab-case.
  1. Html file : Use camel case to name your component and use kebab-case to reference a component in the markup
  2. JavaScript File : Java Script Class name should be in PascalCase
  3. Bundle Component : use camelCase.  

2) Apex

There are two way to call Apex class in Lightning web component.
  1. Imperatively
  2. Wire 
    1. Wire a property
    2. Wire a function  

Wire Vs Imperatively :

As per Lightning component best practices use @wire over imperative method invocation. @wire fits nicely in the overall Lightning Web Component reactive architecture. Salesforce is building some performance enhancement features that are only available with @wire. But there are a few use cases,, that require you to use imperative Apex.

Wire Property Vs Wire Function :

Prefer wiring to a property. This best practice applies to @wire in general (not just to wiring Apex methods).

3) Lightning Data Service

As per LWC best practice use Lightning Data Service functions to create,Record, and delete a record over invoking Apex methods. Yes there are some use cases where you need to multiple records then we can use Apex methods.

Lightning Data Service is built on top of User Interface API. UI API is a public Salesforce API that Salesforce uses to build Lightning Experience. Like its name suggests, UI API is designed to make it easy to build Salesforce UI. UI API gives you data and metadata in a single response

Give preference to user interface form-type in below order.
  1. lightning-record-form : It is the fastest/most productive way to build a form.
  2. lightning-record-view-form : If you need more control over the layout, want to handle events on individual input fields, or need to execute pre-submission
  3. @wire(getRecord) : If you need even more control over the UI, or if you need to access data without a UI

4) Event in LWC


There are typically 3 approaches for communication between the components using events.
  1. Communication using Method in LWC ( Parent to Child )
  2. Custom Event Communication in Lightning Web Component (Child to Parent )
  3. Publish Subscriber model in Lightning Web Component ( Two components which doesn't have a direct relation )
Here is some recommendation for DOM Event.
  1. No uppercase letters
  2. No Spaces
  3. use underscores to separate words
  4. Don't prefix your event name with string "on".

5) Streaming API, Platform Event, Change Data Capture


The lightning/empApi module provides access to methods for subscribing to a streaming channel and listening to event messages. All streaming channels are supported, including channels for platform events, PushTopic events, generic events, and Change Data Capture events. This component requires API version 44.0 or later. The lightning/empApi module uses a shared CometD connection. Example Code.

6) How to debug LWC

Use Chrome pretty JS setting to see unminified JavaScript and Debug Proxy Values for Data. Here is example.
  • Enable Debug mode
    • It gives unminified Javascript
    • Console warnings
    • Pretty data structure
  • Caution - it reduces performance of Salesforce, make sure its disabled in production

7) Use Storable Action

Use Storable Action, It will reduces call to Server. Syntax - @AuraEnabled(cacheable=true)

Caution: A storable action might result in no call to the server. Never mark as storable an action that updates or deletes data.
For storable actions in the cache, the framework returns the cached response immediately and also refreshes the data if it’s stale. Therefore, storable actions might have their callbacks invoked more than once: first with cached data, then with updated data from the server.




Some more key point
  1. Use Playground to markup Custom Components
  2. Use Local Development 
  3. Refer Lightning Web Component Recipe for best practices

Recording

Here is recording of session.



If you missed our first session on Introduction to Lightning Web component then please check our this recording.



Further Learning :

1) Introducing Lightning Web Components Recipes, Patterns and Best Practices


Please check below post on Lightning Web Components:-
  1. Lightning Web Components ( LWC ) in Salesforce with Non-Scratch Org
  2. Design attributes in Lightning Web Components | CSS and SVG Files | Lightning Web Components | targetConfigs
  3. Toast Notification in Lightning Web Components | ShowToastEvent |  (LWC)




Thanks,
Amit Chaudhary

Wednesday, 30 January 2019

Toast Notification in Lightning Web Components | ShowToastEvent | (LWC)


Lets talk about how to fire Toast Notification in Lightning web component | LWC. Toast message is used to pop up the alert message to user. To display toast notification you need to import the ShowToastEvent from lightning/platformShowToastEvent module and dispatch the ShowToastEvent event with message , title and variant.

Syntax 

ShowToastMessage() {
     const toastEvnt = new  ShowToastEvent( {
           title: 'Welcome in Apex Hours',
           message: 'This is your toast message',
           variant: 'info',
     });
     this.dispatchEvent (toastEvnt);

}


Here is sample code:-

toastMessage.html
<template>
    <lightning-card title="Show Toast Message" icon-name="custom:custom56">
        <lightning-input label="Message" value={msg} onchange={msgchange}></lightning-input>
        <lightning-button label="Show Toast Message" onclick={ShowToastMessage}></lightning-button>
    </lightning-card>
</template>


toastMessage.js
import { LightningElement } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class ToastMessage extends LightningElement {
    msg = '';
    msgchange(event){
        this.msg = event.target.value;
    }
    ShowToastMessage() {
        const toastEvnt = new  ShowToastEvent( {
              title: 'Welcome in Apex Hours' ,
              message: this.msg ,
              variant: 'success' ,
        });
        this.dispatchEvent (toastEvnt);
   }
}


toastMessage.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="ToastMessage">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>


Output


Check this post for more detail.

Please check below post on Lightning Web Components:-
  1. Lightning Web Components ( LWC ) in Salesforce with Non-Scratch Org
  2. Invoke Apex Controller from Lightning Web Component | Lightning Web Component inside Another LWC
  3. Design attributes in Lightning Web Components | CSS and SVG Files | Lightning Web Components | targetConfigs
  4. How to get current user id in lightning web component | Access logged in user ID in LWC

Check our YouTube Channel for more recording in Lightning Web Components. 

Thanks,
Amit Chaudhary
amit.salesforce21@gmail.com

Wednesday, 9 January 2019

Design attributes in Lightning Web Components | CSS and SVG Files | Lightning Web Components | targetConfigs



In our last post we talk about How to create first lightning web components and How to invoke apex class from Lightning web components. In this post we will talk about how to create design attribute in lightning web components.

We know how to create Design Attribute in lightning component. For Design Attribute we used to create <design:attribute tag in design file. But for Lightning web components we need to define the design attribute in Component Configuration File (XML) with<targetConfigs> tag. The component author need to defines the property in the component’s JavaScript class using the @api decorator.


We can use Design Attribute to make lightning web components attribute available to System Admin to edit Lightning App Builder or Community. 

Here is Sample code.

HelloWorld.html
<template>
    <lightning-card title={strTitle} icon-name="custom:custom14">
        <div>
            <p>  Hello , {firstName} </p>
        </div>
        <div>
            <template if:true={showImage}>
                <img src={imgUrl} width="200" height="200"/>
            </template>
        </div>
    </lightning-card>
</template>


HelloWorld.js
import { LightningElement, api } from 'lwc';
export default class MyComponent extends LightningElement {
    @api firstName ='Amit';
    @api strTitle ='Welcome in Salesforce';
    @api showImage =false;
    @api imgUrl ='';
}

HelloWorld.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="MyComponent">
    <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__HomePage,lightning__RecordPage">
            <property name="strTitle" type="String" default="Welcome in Salesforce" label="Enter the title"/>
            <property name="showImage" type="Boolean" default="true" label="Show Image ?"/>
            <property name="imgUrl" type="String" default="" label="Enter Image URL"/>
        </targetConfig>
    </targetConfigs>
   
</LightningComponentBundle>

Define the design Attribute in <property tag under <TargetConfig tag.

Please check our YouTube Channel Recording for same topic.

https://www.youtube.com/watch?v=oDj8R8QZdrg&t=1159s




 Please check our old post on Lightning Web Components:-
 
Feel free to post your feedback or question.

Thanks,
Amit Chaudhary

Capture.JPG  @amit_sfdc    #SalesforceApexHours    @ApexHours
  Salesforce Apex Hours


Friday, 21 December 2018

Invoke Apex Controller from Lightning Web Component | Lightning Web Component inside Another LWC


Lightning Web Components are announced as part of Spring19 pre-release. In out last most we talk about how to create first Lightning Web Component. In This post we will talk about how Invoke Apex Controller From Lightning Web Component and how many way we have to call apex class from LWC. 

Call Apex Class / Method:-

Lightning web components can import methods from Apex classes into the JavaScript classes using ES6 import.

import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod';
  • apexMethod—This identifies the Apex method name.
  • Classname— The Apex class name.
  • Namespace—The namespace of the Salesforce organization
After importing the apex class method you can able call the apex methods as functions into the component by calling either via the wire service or imperatively. We have three way to call Apex method
  1. Wire a property
  2. Wire a function
  3. Call a method imperatively.


Tuesday, 18 December 2018

How to call an Apex class from a Lightning Web component (#LWC) | Invoke Apex Controller from Lightning Web Component | imperatively



Welcome in Lightning Web Components world. Last time we talk about how to create first Lightning Web Component and how to configure VsCode with Salesforce CLI.

We know how to Invoke Apex Class from lightning Component. So Today we will talk about how to invoke apex class from Lightning Web Component.

Finally get some time to play with LWC. Let see how to create LWC to Search a Account Record.

Step 1) Create Apex Class to Search Record.
 
public with sharing class AccountController {
    @AuraEnabled(cacheable=true)
    public static List<Account> findAccounts(String searchKey) {
        String key = '%' + searchKey + '%';
        return [SELECT Id, Name, AccountNumber FROM Account WHERE Name LIKE :key  LIMIT 10];
    }
}
Create on Apex Class with @AuraEnabled annotation and method must be static.

Step 2) Create Lightning Web Component in VsCode. IF you don't know how check here.

SearchAccountRecord.html
<template>
    <lightning-card title="Search Account" icon-name="custom:custom57">
        <div class="slds-m-around_medium">
            <lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" label="Search"></lightning-input>
            <template if:true={accounts}>
                <template for:each={accounts} for:item="acc">
                    <li key={acc.Id}>
                        {acc.Name}
                        {acc.AccountNumber}
                    </li>
                </template>
            </template>
        </div>
    </lightning-card>
</template>
  • <lightning-input is replacement of lightning:input in .
  • <template if:true is used for checking if condition.
  • <template for:each for Iteration.


SearchAccountRecord.js
import { LightningElement, track } from 'lwc';
import findAccounts from '@salesforce/apex/AccountController.findAccounts';

/** The delay used when debouncing event handlers before invoking Apex. */
const DELAY = 350;

export default class SearchAccountRecord extends LightningElement {
    @track accounts;
    @track error;
    handleKeyChange(event) {
        // Debouncing this method: Do not actually invoke the Apex call as long as this function is
        // being called within a delay of DELAY. This is to avoid a very large number of Apex method calls.
        window.clearTimeout(this.delayTimeout);
        const searchKey = event.target.value;
        // eslint-disable-next-line @lwc/lwc/no-async-operation
        this.delayTimeout = setTimeout(() => {
            findAccounts({ searchKey })
                .then(result => {
                    this.accounts = result;
                    this.error = undefined;
                })
                .catch(error => {
                    this.error = error;
                    this.accounts = undefined;
                });
        }, DELAY);
    }
}
  • "import findAccounts from '@salesforce/apex/AccountController.findAccounts'" is used to get apex class.


SearchAccountRecord.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="SearchAccountRecord">
     <apiVersion>45.0</apiVersion>
    <isExposed>false</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
  • <targets> is used to to mention where we can use this LWC component
Output :-




Feel Free to share your feedback. I know we can do lots of improvement in this code. I hope this is not a bad start :)


Related Post :-
1) Create First Lightning Wed Component.
2) Developer Tools for Lightning Web Components.
3) Introducing Lightning Web Components.



Thanks,
Amit Chaudhary
amit.salesforce21@gmail.com