Visual Studio Code for Lightning Web Component

There are many tools to develop Lightning Web Component. In this session, we will see how to set up Visual Studio Code for developing Lightning Web Component.

Step 1: Need to install Salesforce CLI (Command Line Interface) using the following link

Windows 32 bit OS -> https://sfdc.co/sfdx_cli_win
Windows 64 bit OS -> https://sfdc.co/sfdx_cli_win64
macOS ->                         https://sfdc.co/sfdx_cli_osx

We will focus on how to set up Visual Studio Code in Windows OS. However, you can set up the Visual Studio Code in macOS.

Step 2: Please set the environment variable in a path in the “Advance Settings” of “My Computer“.

Step 3: Please open the Command Prompt and write “sfdx” and enter. You will see the output like the following image.


 

 

 

 

If you want to see the version of Salesforce CLI, you can enter “sfdx –version“.

Whoever has installed the Salesforce CLI before Spring 19 release, please uninstall and update the Salesforce CLI with the following commands.

sfdx plugins:uninstall salesforcedx
sfdx update

Step 4: Please install the Visual Studio Code from here.

Step 5: Launch Visual Studio Code and Please install the extension named “Salesforce Extension Pack” as per the following image.

Please activate the extension.

Step 6: Please open the Command Palette by Ctrl + Shift + P in the Visual Studio Code and enter SFDX. You will get the SFDX commands just like:

Step 7: Open the Command Palette and search SFDX: Create Project. Just select this and enter Project Name which will be created as part of the SFDX project.

Step 8: Need to connect and authorize the development org. Again Open the Command Palette and search SFDX: Authorize an Org. It will automatically open the default browser where you need to enter the user name and password for your Salesforce Development Org. After authentication, click Allow to successful handshaking between Salesforce and visual Studio Code.

Step 9: Up to this, we have created a project and connected a development org through Visual Studio Code. Now, we will create a Lightning Web Component. Again we need to open Command Palette and search SFDX: Create Lightning Web Component. Press enter to allow the default location and after this enter component name. Remember, all Lightning Web Components will be created under force-app/main/default/lwc.

Here we have created a Lightning Web Component named “welcomeWindow” under “LWCPro” project.

Step 10: We will get three sub-files such as welcomeWindow.html, welcomeWindow.js, welcomeWindow.js-meta.xml for the Lightning Web Component named “welcomeWindow“. Please refer to the next session about the detailed discussion on this Lightning Web Component. For now, we are going to update the sub-files.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                        Welcome to LWC Training Class
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

welcomeWindow.js — currently we will not touch this JS.


welcomeWindow.js-meta.xmlneed to update this file to set the visibility into Lightning App Builder.

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

Step 11: Now, we need to deploy the component. Please do right click on the Component Name from the left side panel of Visual Studio Code and you will find out the command to deploy like SFDX: Deploy Source To Org. After selection of this command, the respective Lightning Web Component will be deployed. If you will get this type of output with exit code 0 in the Visual Studio Code Output Section, that means deployment is successful.

Step 12: Ensure that “My Domain” has been enabled in your Org.

Step 13: Create a Lightning App Page from Lightning App Builder and place the component into the Lightning App Page. Drag this component into the Lightning App page and save & activate it.

Result

14,466 total views, 15 views today

Posted in Lightning Web Component | Leave a comment

Welcome to Lightning Web Component

Definition

Lightning Web Components are built with Custom HTML elements comprises of Salesforce Design Systems and modern Javascript like ES6. Lightning Web Component follows Web Component standards. We can work on Lightning Web Component with the existing web technologies framework.

Why?

All modern web browsers are based on web standards and they are improving their performance every day. Lightning Web Component also follows W3C web component standards to take advantage of modern technologies and native browser’s feature to execute it as fast with the use of minimally network bandwidth.

Remember, as per current Salesforce release (Spring’19), we have to develop Lightning web Component outside of the Salesforce Environment.

Lightning Web Component and Lightning Aura Component can co-exist together in your application. However, you can easily migrate to the Lightning Web Component Model from Lightning Aura Component Model.

 

 

7,266 total views, no views today

Posted in Lightning Web Component | Leave a comment

How to use Salesforce Resources in Lightning Web Component?

Salesforce ResourceSyntax to use
Static Resourceimport sampleResource from '@salesforce/resourceUrl/resourceReference';

Only, we need to enter Static Resource Name in the place of resourceReference and then refer to the property in JS file.If there is a specific namespace in your org, please put the Static Resource Name with the namespace i.e., namespace__StaticResourceName.
Custom Labelimport labelName from '@salesforce/label/labelReference';


Only, we need to enter Custom Label Name with namespace in the place of labelReference and then refer to the property in JS file. If there is no specific namespace in your org, please put the Custom Label Name with default namespace c.
Current User Idimport userId from '@salesforce/user/Id';
SVG ResourceWe can directly write down the SVG in template of the HTML file using tag.
You can also import the SVG from static resource.

9,816 total views, no views today

Posted in Lightning Components | Leave a comment

How to use CSS in Lightning Web Component?

The beauty of Lightning Component Framework is the uniform UI which is consistent in Lightning Design System. So, the styles of Custom Lightning Component and Standard Lightning Component are in uniform. All elements using lightning namespace use Lightning Design System. Also, you can provide slds (Salesforce Lightning Design System) in class attribute of any custom element. Now, we can build the CSS file to provide custom styles for the elements mentioned in the html file.

We can consider the first Lightning Web Component named “welcomeWindow“. Now, we will apply the styles for the welcome content.

Step 1: Need to update the welcomeWindow.js-meta.xml to set the visibility in Lightning App Builder.

welcomeWindow.js-meta.xml

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

Step 2: Need to update the welcomeWindow.html file.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                        Welcome to LWC Training Class
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

Step 3: Create a CSS file named “welcomeWindow.css” under welcomeWindow folder.

welcomeWindow.css

.contentClass{
    color:green;
    font-weight: bold;
}

.messageClass{
    border-top: 1px solid #ccc;
    width:100%;
}

Step 4: Again, we have updated welcomeWindow.html file.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">        
         <div class="messageClass">    
            <lightning-layout>
                    <lightning-layout-item flexibility="auto" padding="around-small">                        
		        <div class="contentClass">                   
                            Welcome to LWC Training Class
                        </div>
                    </lightning-layout-item>
            </lightning-layout>
        </div>
    </lightning-card>     
</template>

Here, we have used messageClass to define the header border and contentClass to define the color of content from the CSS file.

Result

102,123 total views, 12 views today

Posted in Lightning Web Component | Leave a comment

How to use Custom Label in Lightning Web Component?

In this session, we will learn how to use Custom Label in Lightning Web Component.

To do this exercise, We can consider the first Lightning Web Component named “welcomeWindow“.

Step 1: Need to update the welcomeWindow.js-meta.xml to set the visibility in Lightning App Builder.

welcomeWindow.js-meta.xml

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

Step 2: We have created a custom label named “Welcome_Message” where the content will be stored for welcoming.

Step 3: Need to update the JS file.

welcomeWindow.js

import { LightningElement } from 'lwc';
import WELCOME_MESSAGE from '@salesforce/label/c.Welcome_Message';

export default class WelcomeWindow extends LightningElement {
    welcomeMessage = WELCOME_MESSAGE;//'Welcome to LWC Training Class';
}

Here, we have imported Welcome_Message custom label and assign to the “welcomeMessage” property which is referred into the html file. We can import the custom label in this way

@salesforce/label/namespace.customLabelName

In our example, the default namespace is c.

Step 4: Need to update the welcomeWindow.html file.

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                        {welcomeMessage}
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

Here, we have used “welcomeMessage” property to display the welcome message.

Result

8,493 total views, no views today

Posted in Lightning Web Component | Leave a comment

Import/Export JavaScript file in LWC

In ES6 JS architecture, we can export the variables or functions in JS file, so other module can use.

Here, we will create simple calculator using import/export functionality in Lightning Web Component framework. Let’s see.

Step 1: First, we are going to create a LWC named “calculator” where we will define only JS file that is “calculator.js”.

calculator.js

const calculator = (first_param, second_param, mode) => {
    if (mode === "add" || mode === "+" || mode === "Add" || mode === "ADD") {
      return +first_param + +second_param;
    }
  
    if (
      mode === "subtraction" ||
      mode === "-" ||
      mode === "Subtraction" ||
      mode === "SUBTRACTION"
    ) {
      return first_param - second_param;
    }
  
    if (
      mode === "divide" ||
      mode === "/" ||
      mode === "Divide" ||
      mode === "DIVIDE"
    ) {
      return first_param / second_param;
    }
  
    if (
      mode === "multiplication" ||
      mode === "*" ||
      mode === "Multi" ||
      mode === "ADD"
    ) {
      return first_param * second_param;
    }
    return 0;
  };
  
  export { calculator };
  

Here we have defined a function named “calculator” in which there are three parameters such as first_param, second_param and mode which denotes the operation type of calculation.

At last, we have explicitly exported the function as calculator so other LWC can import it.

Step 2: Next, we will create a LWC named “calculation” which will display the result.

So, we need to update the calculation.js-meta.xml to set the visibility in Lightning App Builder.

calculation.js-meta.xml

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

Then, we will write calculation.html file.

calculation.html

<template>
  <lightning-card title="Calculator">
    
<div class="slds-float_right">
      <label class="resClass">{result}</label>
    </div>

    <lightning-layout>
      <lightning-layout-item flexibility="auto" padding="around-small">
        <lightning-input type="number" label="Input 1 " value={input1} onchange={changeInput1}></lightning-input>
        <lightning-combobox label="" value={mode} options={modeOptions} onchange={changeMode}></lightning-combobox>
        <lightning-input type="number" label="Input 2 " value={input2} onchange={changeInput2}></lightning-input>

        
<div class="slds-float_right slds-m-top_medium">
          <lightning-button variant="brand" label="Calculate" onclick={doCalculation}></lightning-button>
          &nbsp;&nbsp;
          <lightning-button variant="brand" label="Reset" onclick={doReset}></lightning-button>
        </div>

      </lightning-layout-item>
    </lightning-layout>
  </lightning-card>
</template>      

Then, we need to update calculation.js file.

calculation.js

import { LightningElement, track } from 'lwc';
import { calculator } from 'c/calculator';

export default class Calculation extends LightningElement {

  @track result = "";
  @track input1;
  @track input2;
  @track mode;

  modeOptions = [
    { label: "+", value: "+" },
    { label: "-", value: "-" },
    { label: "*", value: "*" },
    { label: "/", value: "/" }
  ];

  changeInput1(event) {
    this.input1 = event.target.value;
  }

  changeInput2(event) {
    this.input2 = event.target.value;
  }

  changeMode(event) {
    this.mode = event.target.value;
  }

  doCalculation() {
    /*eslint-disable-next-line*/
    console.log("input1--->" +this.input1 + "input2---->" +this.input2 +"mode--->" +this.mode);
    this.result = calculator(this.input1, this.input2, this.mode);
  }

  doReset(){
    this.input1 = null;
    this.input2 = null;
    this.mode = null;
  }
}

Here, you can see we have imported the function calculator from “calculator.js” file. In doCalculation() function, we have invoked calculator function from calculator.js using three attributes.

At last, we have defined calculator.css file to beautify the output.

calculator.css

.resClass {
    color: green;
    font-weight: bold;
    font-size: 50px;
}  

Result

 

 

 

 

 

 

 

 

So, here we have given the first param as 8, second param as 7, mode of operation as “+” and we will get the result as summation of two integers as 15 in Lightning Web Component through calculator.js file.

49,647 total views, 3 views today

Posted in Lightning Web Component | Leave a comment

Publish Subscriber model in Lightning Web Component

In this Publish Subscriber model, components are not situated in the same DOM tree or in the same containment hierarchy. If the components want to communicate between themselves, we have to use publish subscriber model in Lightning Web Component, You can compare this model as Application Event in Lightning Aura Component.

Publish Subscriber Model Rules

  • Need to use a singleton library which follows the publish-subscriber pattern. Salesforce has already provided one file called pubsub.js by which we can build the publish subscriber communication.
  • import fireEvent from pubsub.js file in the publisher component. Define the pageReference as currentPageReference and fire or publish the event using this pageReference, event name and event detail in the publisher component.
  • import registerListener, unregisterAllListeners from pubsub.js file in the subscriber component. Then register the event and get the value in the subscriber component.

For example, we have made canvas and palette component. When user select the color in palette, canvas will display the respective color. Obviously, palette is the publisher and canvas is the subscriber. Let’s see:

Step 1: First, we need to copy the pubsub.js file from Salesforce library and create the LWC named “pubsub“.

In the pubsub component we only define the pubsub.js file, which will be used later.

/**
 * A basic pub-sub mechanism for sibling component communication
 *
 * TODO - adopt standard flexipage sibling communication mechanism when it's available.
 */

const events = {};

const samePageRef = (pageRef1, pageRef2) => {
  const obj1 = pageRef1.attributes;
  const obj2 = pageRef2.attributes;
  return Object.keys(obj1)
    .concat(Object.keys(obj2))
    .every(key => {
      return obj1[key] === obj2[key];
    });
};

/**
 * Registers a callback for an event
 * @param {string} eventName - Name of the event to listen for.
 * @param {function} callback - Function to invoke when said event is fired.
 * @param {object} thisArg - The value to be passed as the this parameter to the callback function is bound.
 */
const registerListener = (eventName, callback, thisArg) => {
  // Checking that the listener has a pageRef property. We rely on that property for filtering purpose in fireEvent()
  if (!thisArg.pageRef) {
    throw new Error(
      'pubsub listeners need a "@wire(CurrentPageReference) pageRef" property'
    );
  }

  if (!events[eventName]) {
    events[eventName] = [];
  }
  const duplicate = events[eventName].find(listener => {
    return listener.callback === callback && listener.thisArg === thisArg;
  });
  if (!duplicate) {
    events[eventName].push({ callback, thisArg });
  }
};

/**
 * Unregisters a callback for an event
 * @param {string} eventName - Name of the event to unregister from.
 * @param {function} callback - Function to unregister.
 * @param {object} thisArg - The value to be passed as the this parameter to the callback function is bound.
 */
const unregisterListener = (eventName, callback, thisArg) => {
  if (events[eventName]) {
    events[eventName] = events[eventName].filter(
      listener => listener.callback !== callback || listener.thisArg !== thisArg
    );
  }
};

/**
 * Unregisters all event listeners bound to an object.
 * @param {object} thisArg - All the callbacks bound to this object will be removed.
 */
const unregisterAllListeners = thisArg => {
  Object.keys(events).forEach(eventName => {
    events[eventName] = events[eventName].filter(
      listener => listener.thisArg !== thisArg
    );
  });
};

/**
 * Fires an event to listeners.
 * @param {object} pageRef - Reference of the page that represents the event scope.
 * @param {string} eventName - Name of the event to fire.
 * @param {*} payload - Payload of the event to fire.
 */
const fireEvent = (pageRef, eventName, payload) => {
  if (events[eventName]) {
    const listeners = events[eventName];
    listeners.forEach(listener => {
      if (samePageRef(pageRef, listener.thisArg.pageRef)) {
        try {
          listener.callback.call(listener.thisArg, payload);
        } catch (error) {
          // fail silently
        }
      }
    });
  }
};

export {
  registerListener,
  unregisterListener,
  unregisterAllListeners,
  fireEvent
};

Step 2: Then, we need to define palette component named “palettePublisher”.

First, we need to update the palettePublisher.js-meta.xml to set the visibility in Lightning App Builder.

palettePublisher.js-meta.xml

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

Then, we need to write palettePublisher.html file.

palettePublisher.html

<template>
        <lightning-card title="Pallete Publisher">
            <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">
                    <lightning-combobox label="Color" value={color} options={colorCodeOptions} onchange={changeColor}></lightning-combobox>
                    <div class="slds-p-top_small">
                        <lightning-button label="Change Color!" variant="brand" onclick={handleChangeColor}></lightning-button>
                    </div>                    
                </lightning-layout-item>
            </lightning-layout>          
        </lightning-card>
</template>
      

Through this html, user can select the color from the defined picklist, color.

Then, we need to update palettePublisher.js file.

palettePublisher.js

import { LightningElement, track, wire } from 'lwc';
import { CurrentPageReference } from 'lightning/navigation';
import { fireEvent } from 'c/pubsub';

export default class PalletePublisher extends LightningElement {
    @track color;

  @wire(CurrentPageReference) pageRef;

  colorCodeOptions = [
    { label: "green", value: "green" },
    { label: "red", value: "red" },
    { label: "yellow", value: "yellow" },
    { label: "blue", value: "blue" }
  ];

  changeColor(event) {
    this.color = event.target.value;
  }

  handleSearchKeyChange(searchKey) {
    this.searchKey = searchKey;
  }

  handleChangeColor() {
    /*eslint-disable-next-line*/
    console.log("color srs-->" + this.color);
    fireEvent(this.pageRef, "changedColor", this.color);
  }
}

In this js file, we have triggered the event named “changedColor” with color code. Remember, we need to send the page reference attribute as current page reference for successful communication.

Step 3: Need to define the canvas component named “canvasSubscriber“.

First, we need to update the canvasSubscriber.js-meta.xml.

canvasSubscriber.js-meta.xml

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

Then, we need to write canvasSubscriber.html file.

canvasSubscriber.html

<template>
    <lightning-card title="Canvas Subscriber">
        <lightning-layout-item flexibility="grow">
            
<div class="templateBodyClass" style={colorStyle}></div>

        </lightning-layout-item>
    </lightning-card>
</template>      

We are showing the color in canvas based on the selection of color in palette.

Then, we need to write canvasSubscriber.js file.

canvasSubscriber.js

import { LightningElement, track, wire } from 'lwc';
import { registerListener, unregisterAllListeners } from 'c/pubsub';
import { CurrentPageReference } from 'lightning/navigation';

export default class CanvasSubscriber extends LightningElement {
    @track color;
  @wire(CurrentPageReference) pageRef;

  connectedCallback() {
    registerListener("changedColor", this.handleChangedColor, this);
  }

  disconnectedCallback() {
    unregisterAllListeners(this);
  }

  handleChangedColor(colorCode) {
    /*eslint-disable-next-line*/
    console.log("color--->" + colorCode);
    this.color = colorCode;
  }

  get colorStyle() {
    return `background-color: ${this.color}`;
  }
}

In this JS file, we have invoked registeredListener() and unregisterAllListeners() in the respective methods such as connectedCallback() and disconnectedCallback().
From the connectedCallback(), we are calling handleChangedColor() where we have set the color and at last we have used getter method of colorStyle property to set the background color.

To make the style for canvas, we have defined canvasSubscriber.css file.

canvasSubscriber.css

.templateBodyClass {
    height: 80px;
}

Result

 

 

 

 

 

 

 

So, whenever we will select the color in Palette, Canvas will show that color in the screen.

27,865 total views, no views today

Posted in Lightning Web Component | Leave a comment

Custom Event Communication in Lightning Web Component

Custom Event is used in Lightning Web Components(LWC) to make the communication from Child Component to Parent Component in the containment hierarchy. Lightning Web Components can create and dispatch custom events.

Custom Event Rules

  • To create custom events in LWC, need to use CustomEvent() constructor which will contain one required parameter as Custom Event Name and the detail of the event. It will pass any kind of data using detail property.
  • To dispatch custom events in LWC, need to use EventTarget.dispatchEvent() method.
  • To listen the event, we have two types such as Event Listener in Declaratively and Event Listener in Programmatically.
  • We need to add “on” in prefix in the event name in Parent Component during calling of Child Component to make the Event Listener in Declaratively.
  • We need to make the event listener using this.template.addEventListener() or this.addEventListener() in the constructor() of the Parent Component’s JS file as the part of Event Listener in Programmatically.

Let’s see how we will use custom event.

Step 1: First, we will create a child component named “childComponent”.

We will update the childComponent.html.

childComponent.html

<template>
    <lightning-button label="Yes, Papa" onclick={handleResponse}></lightning-button>
</template>

Here, we have declared one lightning-button by which user can send the label of the button to the parent component by handleResponse method.

We need to update childComponent.js file.

import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    handleResponse(event) {
        event.target.disabled = true;
        const btnName = event.target.label;
        const answerEvent = new CustomEvent("answer", { detail: btnName });
        this.dispatchEvent(answerEvent);
    }
}

Here we have defined a method named handleResponse() which has standard event attribute. As per the standard rule of Custom Event creation, we have used CustomEvent() constructor where we have declared the custom event as “answer” and this event will send the label of button (‘Yes, Papa’) via detail property. After that, we have dispatched the custom event using dispatchEvent() method. event.target.disabled equals to true to change the state of the button as disabled after clicked once.

Step 2: Now need to define Parent Component. So, we are going to create a parent component named as “parentComponent”.

We need to update the parentComponent.js-meta.xml to set the visibility into Lightning App Builder.

parentComponent.js-meta.xml

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

Then, we need to work on parentComponent.html file.

parentComponent.html

<template>
        <lightning-card title="Custom Event Communication">
          <lightning-layout>
            <lightning-layout-item flexibility="auto" padding="around-small">
              <div class="padding-around:small">
                {question}
              </div>
              <div class="answClass">
                {answer}
              </div>
              <div class="slds-m-top_medium">
                <c-child-component onanswer={handleAnswer}></c-child-component>
              </div>
            </lightning-layout-item>
          </lightning-layout>
        </lightning-card>
</template>

Here, we have called the child component and used event listener declaratively. We need to add prefix as “on” before the custom event name. As we discussed earlier, we have created a custom event named “answer”. So, in parent component we need to invoke the event listener as handleAnswer using onanswer attribute.

After that, we need to update the parentComponent.js file.

parentComponent.js

import { LightningElement, track } from 'lwc';

export default class ParentComponent extends LightningElement {
    @track answer = "Child: ";
    question = "Parent: Have you completed study for today?";
  
    handleAnswer(event) {
      /*eslint-disable-next-line*/
      console.log("res-->" + event.detail);
      const res = event.detail;
      this.answer = this.answer + res;
    }
}

In the handleAnswer() method, we can get the detail of the event using event.detail.

Now, to make the beautiful UI, we have created on CSS file named parentComponent.css.

parentComponent.css

.answClass {
    color: green;
    font-weight: bold;
  }  

Result

 

 

 

 

 

If you will see the result, parent is asking to child as “Have you completed study for today?” from parent component. Now, Child is trying to give the answer as “Yes, Papa” by clicking the button in Child Component.

How do you use the Event Listener programmatically?

If we will take the same parentComponent.js file, it looks like:

import { LightningElement, track } from 'lwc';

export default class ParentComponent extends LightningElement {
    @track answer = "Child: ";
    question = "Parent: Have you completed study for today?";

    constructor() { 
      super();     
      this.template.addEventListener('answer', this.handleAnswer.bind(this));
    }
  
    handleAnswer(event) { 
      /*eslint-disable-next-line*/
      console.log("res--&gt;" + event.detail);
      const res = event.detail;
      this.answer = this.answer + res;
    }
}

To add an event listener to an element with in a shadow boundary, please use this.template.addEventListener() method, but to add an event listener to an element that the template doesn’t own, please use this.addEventListener() method directly.

Then , need to remove onanswer attribute during the calling of the child component from parentComponent.html file.

You can set bubbles equals to true during creation of the custom event just like:

import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    handleResponse(event) {
        event.target.disabled = true;
        const btnName = event.target.label;
        const answerEvent = new CustomEvent("answer", { detail: btnName, bubbles: true });
        this.dispatchEvent(answerEvent);
    }
}

 

25,185 total views, 15 views today

Posted in Lightning Web Component | Leave a comment

Communication using Method in LWC

Just like Aura framework, we can call the method of Child Component from the Parent Component. In this communication, flow is from Parent Component to Child Component.

We can take one assignment that is when user will enter any phrase, it will be converted to all in capital letter.

Let’s see, how we can use the Method to complete this assignment.

Step 1: First, we have to create the Child Component called “changeCase” where upper case conversion method needs to be built.

changeCase.html | to show the phrase in caps

<template>
    {updatedCase}
</template>

updatedCase attribute is defined by which user can get the result.

Step 2: Then, we have to write the JS file.

changeCase.js| contains conversion logic

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

export default class ChangeCase extends LightningElement {
    @track updatedCase;

    @api 
    changeUpperCase(phrase){
        this.updatedCase = phrase.toUpperCase();
    }
}

updatedCase property is defined as private reactive property so when the value is changed, the component is rendered.
changeUpperCase method is declared as public with @api decorator so another component can call this method. We have used standard javascript function toUpperCase() to convert the phrase as in Capital.

Step 3: Now, we will create the parent component named “changeCaseMethodCaller” which will call the method of the child component.

changeCaseMethodCaller.html | parent component to call child component “changeCase”

<template>
    <lightning-card title="Calling a Method">    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small"> 
                    <lightning-input label="Input Phrase" onchange={handlePhraseChange}></lightning-input>
                 
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto" padding="around-small"> 
                    <label class="slds-text-body_regular">Output Phrase</label>
                    <c-change-case></c-change-case>
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>     
</template>

We have called the child component using kebab case such as <c-change-case></c-change-case>.

Step 4: We need to write the JS file in this way.

changeCaseMethodCaller.js | to call the child component

import { LightningElement } from 'lwc';

export default class ChangeCaseMethodCaller extends LightningElement {

    handlePhraseChange(event){
        this.template.querySelector('c-change-case').changeUpperCase(event.target.value);
    }
    
}

Here, please notice that changeUpperCase method of the child component is invoked using this.template.querySelector.

Step 5: After this, we need to update the js-meta.xml file to visible the component in the app builder.

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

Step 6: At last, need to add the Parent Component into Lightning App Page/Record Page/ Home Page.

Result

 

 

 

 

 

Here, we have entered a phrase as “Hello My Friend”, LWC is showing the phrase in capital letter as “HELLO MY FRIEND“.

What is the  difference between querySelector and querySelectorAll()?

querySelector() returns the first element that matches the selector in DOM, whereas querySelectAll() returns the array of DOM elements if we will pass the parameter as class or data-* value.

It is recommended that do not use the HTML id as querySelector() parameter  due to the id has been changed to global id during HTML rendering.

 

23,232 total views, 3 views today

Posted in Lightning Web Component | Leave a comment

What are the type of properties in LWC JS file?

In LWC JS file, we have declared property with camel case to map attribute with kebab case in LWC HTML file.Whenever we will speak about attribute means we are referring HTML file and whenever we will speak about property means we are referring JS file.

Basically, there are two types of properties such as Reactive Properties and Private Properties.

Reactive Properties has of three types such as Public Property, Tracked Property & Boolean Property.

Reactive Properties

Public Property: If you want to make the property to be called from other component, you need to declare this property with @api decorator in the calling component. Along with this, if the value changes on this property, component will be re-rendered automatically. That’s why, it’s reactive.

Track Property: If you want to track the property’s value, you need to declare this property with @track decorator. Along with this, if the value changes on this property, component will be re-rendered automatically. That’s why, it’s reactive. Track property is also called private reactive property. Because, caller component or component A can not call with @track decorator property to the calling component or component B.

Boolean Property: By default, Boolean Property has the value of false. If you call the component with just  Boolean Property name, the Boolean value would be true and component will also be re-rendered due to @api decorator. That’s why, it’s reactive.

Private Property

Private Property can be used only by the JS class in JS file. If the value changes on private property, the component doesn’t re-render. So, it’s not reactive. You should not put any decorator (@api, @track) for declaration of private property.

Assignment

Let’s say, we will show the incremental value in a child component, but when parent component will instruct to show the incremental value one by one at that point of time, child component will work.

Solution

So, we have created two  Lightning Web Components such as incremental(Child Component) and callIncremental(Parent Component). Let’s focus on child component, incremental.

Step 1: create one LWC named incremental.

Step 2: open the incremental.html file

incremental.html | to show the incremental value one by one


<template>
    <lightning-card title={sectionName}>    
        <lightning-layout>
                <lightning-layout-item flexibility="auto" padding="around-small">                    
                    <template if:true={enableIncrement}>
                        {incrementValue}
                        <lightning-button label="+" variant="brand" onclick={increment} class="slds-m-left_large"></lightning-button>
                    </template>
                </lightning-layout-item>
            </lightning-layout>
    </lightning-card>  
</template>

Step 3: open the incremental.js file

incremental.js | to define the attributes


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

export default class Incremental extends LightningElement {
    @api sectionName;
    @api enableIncrement;
    @track incrementValue = 1;
    incrementBy = 1;

    increment(){
        this.incrementValue = this.incrementValue + this.incrementBy;
    }

}

Here, we have declared sectionName, enableIncrment as the public property with @api annotation that means we will send the value for these properties from other component named “callIncremental”. As Reactive Properties rule, if the values are changed to the properties, the component will be rerendered automatically.

We have defined incrementValue property with @track decoration to calculate the incremental value which will be visible in the screen by clicking  [+] button.

Step 4: create another LWC named, callIncremental which is the parent component.

Step 5: we need to place this parent component in Lightning Experience. So, we need to update the respective js-meta.xml file.

callIncremental.js-meta.xml


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

Step 6: Please open callIncremental. html file and call the child component, incremental with certain attributes.

callIncremental. html | to call the incremental component


<template>
    <c-incremental enable-increment section-name="Increment One by One"></c-incremental>
</template>

Here, you can see that we have used kebab case during call the child component “incremental”.

Result

 

 

 

 

Notes

Remember, you can not set the public property(@api) in the current component’s js file. Remember, you can only set the value of a public property during component construction time means you can only send the value for public property.

For example, If we will set the public property named “sectionName” in our “incrmental” component,  we will not get this section name in the output.

22,932 total views, 3 views today

Posted in Lightning Web Component | Leave a comment