How to refresh Lightning Data Table after triggering standard event(new/edit)?

How to refresh Lightning Data Table after triggering standard event(new/edit)? 

 

 

 

 

 

 

 

 

In general way, if we will try to create a new record by NavigationMixin Create event from Lightning Data Table, it will be redirected to the detail page of newly created record, but if business wants to update the Lightning Data Table without navigating to the detail page of newly create record what will we do?

In the same way, if we will try to update the record by NavigationMixin Edit event from Lightning Data Table, the columns will not be refreshed until refreshing the entire page. In this situation how will we mitigate this problem?

I think, using the following solution all the said problems will be resolved and it will help many LWC developers to make the customer happy.

Let’s discuss about this solution:

Following steps need to be performed for this solution:

  1. Create Platform Event
  2. Create Trigger and TriggerHandler to publish the Platform Events
  3. Create Apex Class to get the records from Server
  4. Create LWC with Lightning Data Table with empAPI

Here, we will show the account records in Lightning Data Table and try to edit any account record and create a new account record from this table.

1. Create Platform Event: Now, we will create Platform Event named “Refresh Record Event” as per the following image and create two text fields with length of 18 such as “Record Id” and “User Id”.

 

2. Create Trigger and TriggerHandler to publish the Platform Events: Here, at first we will create a TriggerHandler named “AccountTriggerHandler” in this way:

In this class, we are publishing Platform Event records at the time of insert and update operations on Account records. We have added Record Id and Current User Id on each platform event records.

Next, we will create a Trigger on Account object such as

3. Create Apex Class to get the records from Server: Now, we will create an Apex Class named “DataTableActionsController” for our LWC to get the Account records.

Here for demo purpose, we have limited only two account records which will be returned to the next Lightning Web Component (LWC).

4. Create LWC with Lightning Data Table with empAPI: Now, finally we will create the LWC named “dataTableActions” with empAPI event:

dataTableActions.js-meta.xml

dataTableActions.js

We have taken following actions in this js file.

  • We have imported Apex Class Method (“getAccounts“) to get the account records.
  • NavigationMixin is being used to take the standard create and edit operation.
  • We have imported current user id to check the current logged in user.
  • Then we have imported the empAPI with some useful methods such as subscribe, unsubscribe, onError.
  • First, we have defined the channel name as  “/event/Refresh_Record_Event__e” and subscribed the channel in connectedCallback() method.
  • Next, we have defined the messageEvent() method to notify any change on the record.
  • Lastly, we have unsubscribed the channel during the termination of the component.
  • Remaining codes, we have written for showing the records with specific columns for the Lightning Data Table.
  • Please noted that, when we have used NavigationMixin Create event in createAccount() method, we have put “state” with “navigationLocation” parameter as “RELATED_LIST” to stop the navigation to the detail page of newly created account record.

dataTableActions.html

In this html, we have defined the Lightning Data Table with row actions to show the records with specific actions such as “Edit”.

So, we have solved the problem to refresh the data table without entire page refreshing when we will use standard create/ edit event from NavigationMixin library.

Thank you!

 

20,423 total views, 11 views today

How to read Page Layout in LWC?

In this section, we will learn how to use getRecordUi in our Lightning Web Component(LWC).
We will build one LWC by which we can show Account Information by using the same Account record id for learning purposes. We will do this by “getRecordUi” function.

Basically, getRecordUi is used to get metadata information of the records in Salesforce. By this function, we will read the Account Page Layout and read the value of some fields present in that Page Layout.

So, we have created one LWC named “showAccountInfobyRecordUi”.

Step 1: Update showAccountInfobyRecordUi.xml file to enable the LWC for Lightning Pages.

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

Step 2: Need to update showAccountInfobyRecordUi.js file as per following code snippet

import { LightningElement, api, wire } from "lwc";
import { getRecordUi } from "lightning/uiRecordApi";

export default class ShowAccountInfobyRecordUI extends LightningElement {
  @api recordId;
  accountName;
  accountNumber;

  @wire(getRecordUi, {
    recordIds: "$recordId",
    layoutTypes: "Full",
    modes: "View",
  })
  wiredRecord({ error, data }) {
    if (data) {
      this.accountName = data.records[this.recordId].fields["Name"].value;
      this.accountNumber =
        data.records[this.recordId].fields["AccountNumber"].value;
    } else{
      // TODO: Data handling
    }
  }
}

We need to maintain the following steps to use “getRecordUi” function.

  • First, we need to import “getRecordUi” from “lightning/uiRecordApi”.
  • Next, we need to invoke “getRecordUi” method using the wire adapter and we need to pass the layout type and mode as described in the code snippet. This will return the value of all the fields resides in the Page Layout.
    • layout types can be ‘Compact’ or ‘Full’ and modes can be ‘Create, ‘Edit’ or ‘View’
  • Here, we want to fetch Account Name from the fields returned by this getRecordUi function by writing this code:
    data.records[this.recordId].fields["Name"].value
  • We are able to access fields from the Account Page Layout by using the “getRecordUi” function.

Step 3: Now, we have to update the showAccountInfobyRecordUi.html file to show the Account Name and Account Number.

<template>
  <lightning-card title="Account Information">
    <lightning-layout>
      <lightning-layout-item padding="around-small">
        Account: {accountName} <br />
        Account Number: {accountNumber}
      </lightning-layout-item>
    </lightning-layout>
  </lightning-card>
</template>

Step 4: Place this component in any Account record page and we will get this following output

33,895 total views, 6 views today

How to increase the width of Quick Action and call the LWC from Quick Action?

Problem Statement: In many projects, I got the requirement to call the Lightning Web Component from Quick Action, but the width of that Lightning Web Component is almost 80% of the screen. How can you accomplish this?

Solution: We all know how to invoke Lightning Web Component from Lightning Aura Component which can be associated with the Quick Action in Salesforce Lightning Experience. Now, if we will open any Quick Action settings, we can update the height of the standard quick action modal as per business requirement, but what we will do if we have to increase the width of the standard quick action modal. Here is the solution.

If we will try to use standard slds class such as “slds-modal_container, we can increase the width of the standard quick action modal, but in this case, other modals such as Edit or any other quick action will be affected. So, we should not consider this approach.

First, we will try to hide the Standard Quick Action Modal and at the same time we will invoke the Lightning Web Component using lightning:overlayLibrary with attaching the standard cssClass as “slds-modal_large“.

We will describe this with an easy example. Let’s say, we want to show a greeting message from a Quick Action on the Lease Record Detail Page.

Step 1: We will create two components such as Aura Component and Lightning Web Component. First, we will create a Lightning Web Component named “greeting” in which will show the greeting message such as

greeting.html

<template>
    <lightning-card title="Welcome My Friends">
        <lightning-layout>
            <lightning-layout-item flexibility="auto" padding="around-small"> 
                
<div class="contentClass">                   
                    I hope you are doing well.
                </div>

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

we don’t need to write anything in js or xml file. Because we will call this component from the Aura Component which will be associated with the Quick Action in Salesforce Lightning.

Step 2: Create a Lightning Aura Component named “showMessage” which will be associated with the Quick Action.

showMessage.cmp

<aura:component implements="force:lightningQuickActionWithoutHeader"> 
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> 
    <lightning:overlayLibrary aura:id="overlayLib"/>
</aura:component>

If you see, we have used standard lightning:overlayLibrary to open a modal when the user will click on Quick Action.

showMessageController.js

({
    doInit : function(component, event, helper) {        
        var modalBody;
        
        setTimeout(()=>{  
            // Priority -> 1 || Please check if it will not work, consider Priority 2.
                //$A.get("e.force:closeQuickAction").fire(); 
        
            //Priority -> 2
                var stdModal = document.getElementsByClassName("uiModal forceModal");    
                stdModal.forEach(function(a, b) {
                $A.util.addClass(a, "slds-hide");
                });        
        },10);  
    
        $A.createComponent("c:greeting", {},
        function(content, status) {
            if (status === "SUCCESS") {
                modalBody = content;
                component.find('overlayLib').showCustomModal({
                    header: "Greeting Message",
                    body: modalBody,
                    showCloseButton: true,
                    cssClass: "slds-modal_large",
                    closeCallback: function() {                       
                    }
                })
            }
        });  
    }                
})

Now, we will discuss about two operations such as setTimeOut() and $A.createComponent() used in doInit() method.

setTimeOut(): We are hiding the standard quick action modal by applyting “slds-hide” class to the standard quick action modal class in 10ms. However, please try this standard quick action closure function

$A.get("e.force:closeQuickAction").fire();

first, if it will not work then use the “slds-hide” class to the standard quick action modal class as the second approach.

$A.createComponent(): We are calling our “greeting” component using this function with lightning:overlayLibrary. We have set the cssClass as “slds-modal_large” to increase the width of the modal in where Lightning Web Component will be invoked.

Step 3: Now, we will attach this Lightning Aura Component to the Quick Action of Lead Object(for example).

Quick Action: Show Message

 

 

 

 

 

 

 

 

 

 

Place this Quick Action into the Lead Page Layout.

Result: Open the Lead record and click on “Show Message” quick action, you can see the greeting Lightning Web Component Modal window on the detail page as per the following image. Actually, when it’s opened, in backend standard quick action modal is disappeared.

 

Thanks for your time!!

43,554 total views, 9 views today

Introduction of Jest – JavaScript Testing Framework

What is Jest?
Jest is a JavaScript Testing Framework for the client-side application using Node, Babel, React, TypeScript, Angular as well as Lightning Web Component and more. Jest is a JavaScript library and it is distributed as an NPM package.

We will learn how to use Jest to test our Lightning Web Component in the next chapter. Before that, we need to know the basic idea of Jest to test any JavaScript file. Let’s start:

Now, we will test our own sample js file which will return the “Hello World!” message.

Step 1: Let’s say, we have created one folder called “JestTest” where we will create the sample js file.

Step 2: We have created one sample js file named “helloWorld.js” which will return the message “Hello World!“.

function helloWorld(){
    return 'Hello World!';
}
module.exports = helloWorld;

Here, we have given provision to access this js function from other js files in the same folder using “module.exports” feature.

Step 3: Now, we have to install Jest library by running the following command in the terminal from the VS Code or from CLI. It will take little time to install. After successful installation, you can see the sub-folder named “node_modules” in your main directory/folder.

npm install --save-dev jest

Step 4: Till now, we didn’t get package.json file where we can derive the test commands. For that, we have to run the following command “npm init” from the terminal. It will ask so many questions about your project configuration. But, you can leave as it’s blank for now. After successful execution, you can see the package.json file has been created.

Step 5: So, in package.json file, we have to update the following commands:

"scripts": {
    "test": "jest"
 },

Jest Configuration is done. Excellent Job !!

Step 6: Now, we will create the test file. Naming Convention would be mainFileName.test.js. So, we have created a test file named “helloworld.test.js” to test our helloWorld function. In this file, we have imported our original “helloWorld.js” function by using require statement.

const helloWorld = require('./helloWorld');

describe('helloWorld', () => {
    it('displays message', () => {
        expect(helloWorld()).toBe('Hello World!');
    });
});

We can describe the blocks in this way:

  • describe() block is nothing but a test suite. It can be used to test more business use cases.
  • it() block defines the test block. A single it() block describes a single test. We can use test() block instead of it() block.
  • expect() block is the assertion statement and it returns boolean variable depends on the matching between real value and expected value.

Step 7: Now, we will run the following command from the terminal of the VS Code to test our helloWorld function.

npm test

Result:

 

 

 

 

 

 

 

Here, we can see our test case is passed by matching “Hello World!” statement.

Step 8: If we want to see code coverage, we have to update the scripts in the package.json file.

"scripts": {
    "test": "jest --coverage"

  },

Step 9: Now, run the same Jest runner syntax from the terminal such as “npm test” just like Step 7.

Result:

 

 

 

 

 

 

 

 

 

Step 10: If you want to see the collective coverage report in HTML for all the js files in the same folder, you have to include the jest commands after scripts in your package.json file.

"jest": {
    "coverageReporters": ["html"]
  },

Now, the entire package.json file looks like

{
  "name": "jesttest",
  "version": "1.0.0",
  "description": "",
  "main": "helloWorld.js",
  "dependencies": {
    "jest": "^24.9.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "jest --coverage"

  },
  "jest": {
    "coverageReporters": ["html"]
  },
  "author": "",
  "license": "ISC"
}

Step 11: Again, we have to run “npm test” command and we will get one sub-folder called “coverage” in your main directory/folder named “JestTest“. In the Coverage folder, please run the “index.html” file to check the entire coverage report in HTML just like:

If you want to learn more about Jest, please read the reference document of Jest library from the following link: https://jestjs.io/

Enjoy! We have explored the fundamentals of Jest. In the next chapter, we will learn Jest for Lightning Web Component.     

Thank you! 

9,321 total views, 6 views today

Test LWC with Jest

Jest is a powerful JavaScript testing framework for the client-side project. It’s supported in any React Application, Node, Babel, TypeScript as well as Salesforce Lightning Web Component.Jest uses jsdom to provide an environment like a browser’s Document Object Model(DOM).

Jest can be used for

  • Test a component in isolation
  • Test a component’s public API (@api properties and methods, events)
  • Test basic user interaction (clicks)
  • Verify the DOM output of a component
  • Verify that events fire when expected

In this session, we will see how to test a simple Lightning Web Component using Jest framework.

To test Lightning Web Component, need to install sfdx-lwc-jest and its dependencies into Salesforce DX Project. jsdom is downloaded during the installation of lwc-jest.

First, we need to set up the environment to work with Jest in Salesforce DX project.

  • Install Node.js from this link:  https://nodejs.org/en/, if you have not installed in your computer yet. Set the Environment Path to access npm from any drive location.
  • Generally, Salesforce DX Project doesn’t have a package.json file. Run the following command as “npm init” from the terminal of the Visual Studio Code and it will create a package.json file in the project directory. After “npm init” execution, system will ask you the project information, for now you can keep it as blank. You just need to enter until package.json file has been created.
  • To install lwc-jest and its dependencies, please run the following commands one by one:
npm install
npm install @salesforce/sfdx-lwc-jest --save-dev

It will take some time to complete the downloading of sfdx-lwc-jest and its dependencies in your SFDX project library.

  • Need to update the <scripts> block of the package.json file by adding the following codes.
"test:unit": "lwc-jest",
"test:unit:watch": "lwc-jest --watch",
"test:unit:debug": "lwc-jest --debug",
"test:unit:coverage": "lwc-jest --coverage"

N.B.- Please check the latest release on sfdx-lwc-jest, may be you need to update “lwc-jest” to “sfdx-lwc-jest” for “test:unit” snippet if the upper code snippets will not work.

  • Create a folder named “__tests__” in the specific Lightning Web Component folder in the SFDX project.
  • Update the .forceignore file to ensure that the files of the “__tests__” folder should not be deployed during deployment of the lightning web component into the Salesforce Org. Please update the “.forceignore” file  according to the following line:

           **/__tests__/**

Setup is done. Awesome!! You have done a great job. Take rest..we will move to the next section how to run Jest to test Lightning Web Component.

Naming Convention of Test File: LightningWebComponentName.test.js

Now, we will create the test file into the “__tests__” folder.

Let’s say following is the Lightning Web Component named “welcomeWindow”

welcomeWindow.html

<template>
    <lightning-card title="Welcome My Friends">
        <div class="messageClass">    
            <lightning-layout><!--if horizontal-align="space", all layout items will be in center-->
                    <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>

After that, we will create a welcomeWindow.test.js file into the “__tests__” folder. Now we will write the code into this file like:

welcomeWindow.test.js

import { createElement } from 'lwc';
import WELCOMEWINDOW from 'c/welcomeWindow';

describe('c-welcome-window', () => {
    afterEach(() => {
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
    });

    it('displays greeting', () => {
        // Create element
        const element = createElement('c-welcome-window', {
            is: WELCOMEWINDOW
        });
        document.body.appendChild(element);
        // Verify displayed welcome message
        const div = element.shadowRoot.querySelector('div');
        expect(div.textContent).toBe('Welcome to LWC Training Class');
    });
});

Clarification of the welcomeWindow.test.js file

  • Imports standard methods: First, we need to import the standard “createElement” method and import the Lightning Web Component to test. Here, we will test “welcomeWindow” Lightning Web Component.
  • Describe() block: Next, we will focus on the describe block. This block is nothing but a test suite. A single describe block can be used to test more business cases. afterReach() method resets the DOM at the end of the test.
  • it block: We can say it block as test block. A single it block describes a single test.
  • Component Creation: In the it block, we need to create an instance of the original LWC to test by “createElement()” method.
  • Adding the Component into DOM: After that, we need to add the component instance into the DOM by appendChild method.
  • Asserts: Now, we need to elements from the DOM using querySelector() method. Finally, we need to put the expect statement which is an assertion of the success condition. Here, we have written just like:

expect(div.textContent).toBe(‘Welcome to LWC Training Class’); //where the value of div.textContent will match the                     string in toBe() method.

Jest supports lots of matchers like toBe and toMatchObject. Please check all the methods from this link:
https://jestjs.io/docs/en/expect

How to run the test?

Now, we need to run the following code in the terminal of VS Code to test our lightning component.

npm run test:unit

When this command will be executed, it will run the respective code snippet “lwc-jest” mentioned in the script block of the package.json file.

So, after running this command, we will get the following output in the terminal of our VS Code.

 

 

 

 

 

 

 

if we will update the welcomeWindow.test.js file with line no. 19 as

expect(div.textContent).toBe('Welcome to Lightning Web Component Training Class');

and run the unit test again, we will see the error message as mentioned in the following image


 

 

 

 

 

 

 

 

 

 

 

Thank you!! So, we have explored how to test a simple Lightning Web Component(LWC) with Jest library. In the next session, we will see how to test LWC with the different type of decorators.

18,336 total views, 6 views today

DOM Manipulation in Lightning Web Component

In this session, we will learn how to manipulate DOM Tree in Lightning Web Component.

What is DOM?

  • The acronym of DOM is “Document Object Model”.
  • DOM is a programming API for HTML & XML.
  • DOM is a logical structure(tree) of the document.

When DOM is created?
At the time of loading HTML/XML, DOM is created.

Please see my video on youtube on regarding this DOM Manipulation in Lightning Web Component

 

 

To understand DOM Manipulation, we have created one Lightning Web Component (LWC) named “showContactsPanel” by which we can show the Contact records based on an account.

Please download this LWC from the following URL:

https://github.com/SantanuatGithub/DOMManipulation.git

According to the showContactsPanel.html file, DOM Tree looks like

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Generally, in HTML, we can access particular node with respect to Id, Class, Tag by using document.getElementById(“#Id”), document.getElementsByClassName(“.Class”), document.getElementsByTagName(“h1”) or by using this.document.querySelector().

To manipulate the DOM in LWC, we will use this.template.querySelector() where “template” is the root node in LWC.

Steps to execute

  • Deploy the downloaded “showContactsPanel” LWC with Apex Class.
  • Add this LWC into any Lightning Page and assign to any Lightning Application.
  • Need to focus on manipulateDOM() method in the JS file.
  • Uncomment the lines for the particular scenario just as mentioned in the Video. Please do not uncomment all the lines in this method.
  • Refresh the Page in Lightning Experience.
  • Click on “Check DOM” button to see the output. May be, browser console need to be opened to see the output for certain test cases.

 

//Read Header from lightning-card
console.log(‘Lightning Card Header–>’+this.template.querySelector(‘lightning-card’).title);
we can also use “main” class to get the title by using this.template.querySelector(‘.main’).title
//Change Title
this.template.querySelector(‘lightning-card’).title = “Learning DOM Manipulation in Lightning Web Component”;
//get text content
console.log(‘Content–>’+this.template.querySelector(‘.main’).textContent);
We can use textContent to get the value of a particular node.
//Change content color of the lightning-card
this.template.querySelector(‘lightning-card’).style.color=’green’;
//add same style from CSS file
this.template.querySelector(‘lightning-card’).classList.add(‘panelHeader’);
//get the contacts sequentially
let contactList = this.template.querySelectorAll(‘.conName’);
console.log(‘Contact 1–>’+contactList[0].textContent);
console.log(‘Contact 2–>’+contactList[1].textContent);
//get the length of the list
console.log(‘ConList–>’+contactList.length);
//change the color of last element
contactList[contactList.length-1].style.color=’red’;
//get first item
let firstItem = this.template.querySelector(‘.conName:first-child’);
console.log(‘firstChild–>’+firstItem.textContent);
//get last item
let lastItem = this.template.querySelector(‘.conName:last-child’);
console.log(‘lastChild–>’+lastItem.textContent);
//get nth Item
let nthConItem = this.template.querySelector(‘.conName:nth-child(2)’);
console.log(‘nthItem–>’+nthConItem.textContent);
//Stripped Table by DOM Execution
let contactOddList = this.template.querySelectorAll(‘.conName:nth-child(odd)’);
let contactEvenList = this.template.querySelectorAll(‘.conName:nth-child(even)’);
for(let i = 0; i < contactOddList.length; i++){
contactOddList[i].style.backgroundColor = ‘#D5DBDB’;
contactEvenList[i].style.backgroundColor = ‘#BDC3C7’;
}
//get the parent node
let contempList = this.template.querySelector(‘.contempList’);
console.log(‘parent node–>’+contempList.parentNode);
//get the parent node content
console.log(‘parent node–>’+contempList.parentNode.textcontent);
change the color of parent node
contempList.parentNode.style.color=”red”;
//get the child node
let parentContempList = this.template.querySelector(‘.parentContempList’);
console.log(‘child node–>’+parentContempList.children[0]);
//get the child node content
//console.log(‘child node–>’+parentContempList.children[0].textContent);
//change the color of child nodes
parentContempList.children[0].style.color=”green”;
parentContempList.children[1].style.color=”red”;
//set the child node contents
parentContempList.firstElementChild.textContent = “Displaying Data”;
parentContempList.lastElementChild.textContent = “Transferred Rows”;
//get attribute at certain level
letcontactList=this.template.querySelectorAll(‘.conName’);
for(let k=0; k<contactList.length; k++){
console.log(contactList[k].getAttribute(‘id’));
}
Q: Now, we want to see the Contact detail by clicking a button for every row. How can we achieve it?
If you open the “showContactsPanel” LWC, you can see entire second <tr> was commented in the table. Please uncomment this row and refresh the page. Now, you can see the specific Contact detail by clicking on each row.
We will analyze toggleRow() method in the JS file.
toggleRow(event){

        event.preventDefault();

        this.recId = event.target.dataset.id;
        
        //get the attribute of DOM element using wild characters
        //let currentElement = this.template.querySelector("[id^='" + this.recId + "']");
        //console.log('currentElement-->'+currentElement.textContent);

        
        this.recId = event.target.dataset.id;
        let conList = this.template.querySelectorAll('.conli');

        let btnList = this.template.querySelectorAll('.btn');

        for (let j = 0; j < btnList.length; j++){
            btnList[j].iconName = "utility:chevronright";
        }

        
        for (let i = 0; i < conList.length; i++){
            let indvRow = conList[i];
            let indvRowId = conList[i].getAttribute('id');  
            
            if(indvRowId.includes(this.recId)) {
                if(indvRow.classList.contains("slds-show")){
                    indvRow.classList.add("slds-hide");
                    indvRow.classList.remove("slds-show");
                    event.target.iconName = "utility:chevronright";
                }
                else{
                    indvRow.classList.remove("slds-hide");
                    indvRow.classList.add("slds-show");
                    event.target.iconName = "utility:chevrondown";
                }
            }
            else{
                indvRow.classList.add("slds-hide");
                indvRow.classList.remove("slds-show");
            }
        }
    }    
We have used data-id attribute in <lightning-button-icon> where data-id attribute contains the specific record id. If we want to get this record id on clicking, we have to use event.target.dataset just like event.target.dataset.id. After that, we need to compare the record id with the entire DOM to close the other rows’ panels and open the particular row panel for the specific Contact record just like
                                                                                    Thank you !!

 

 

22,649 total views, 10 views today

Showing Static Record using Apex to Wire Mechanism

Now, we will see how to get Salesforce data as static way using Apex.

We have built a LWC named “showWireApexStaticContact“.

Step 1: We have created an Apex Class named “LWC_ContactController” by which we will send the Contact record to Lightning Web Component. We can use the same class.

LWC_ContactController.cls

public with sharing class LWC_ContactController{
	@AuraEnabled(cacheable=true)
	public static Contact getStaticContact(){
		return [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 1];
	}
}

getStaticContact() method returns the Contact Record.

Step 2: As per previous examples, we need to update the “showWireApexStaticContact.js-meta.xml” file to set the visibility in Lightning App Builder.

showWireApexStaticContact.js-meta.xml

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

Step 3: Need to write the respective HTML file.

showWireApexStaticContact.html

<template>
        <lightning-card title="Showing Static Record (Wire * Apex)">            
            <lightning-layout> 
              <lightning-layout-item flexibility="auto" padding="around-small">
                   Contact
                   <template if:true={contactObj.data}> 
                        <div class="slds-m-around_medium">
                            <p>{name}</p>
                            <p>{phone}</p>
                            <p><lightning-formatted-email value={email}></lightning-formatted-email></p>
                        </div>
                    </template>
                    <template if:true={contactObj.error}>
                        {contactObj.error}>
                    </template>
              </lightning-layout-item>
            </lightning-layout>
        </lightning-card>
</template>

Step 4: Now, we need to work on the JS file.

showWireApexStaticContact.js

import { LightningElement, wire } from 'lwc';
import { getSObjectValue } from '@salesforce/apex';
import getStaticContact from '@salesforce/apex/LWC_ContactController.getStaticContact';

import CONTACT_NAME_FIELD from '@salesforce/schema/Contact.Name';
import CONTACT_PHONE_FIELD from '@salesforce/schema/Contact.Phone';
import CONTACT_EMAIL_FIELD from '@salesforce/schema/Contact.Email';

export default class ShowStaticContact extends LightningElement {

    @wire(getStaticContact) contactObj;

    get name(){
        return this.contactObj.data
            ? getSObjectValue(this.contactObj.data, CONTACT_NAME_FIELD)
            : '';
    }

    get phone(){
        return this.contactObj.data
            ? getSObjectValue(this.contactObj.data, CONTACT_PHONE_FIELD)
            : '';
    }

    get email(){ 
        return this.contactObj.data
            ? getSObjectValue(this.contactObj.data, CONTACT_EMAIL_FIELD)
            : '';
    }
}

We have imported getSObjectValue from ‘@salesforce/apex’ and getStaticContact from our own Apex Class “LWC_ContactController” to get the Contact record.

In all getter functions(name.phone..), System will find out the specific field from the entire Contact Record by getSobjectValue() function.

Step 5: Need to add this component into Lightning App/Home or Record Page.

Result

10,481 total views, 15 views today

Showing Static Record using Apex to Imperative Mechanism

Now, we will see how to get Salesforce data as static way using Apex with Imperative way.

We have built a LWC named “showImperativeApexStaticContact“.

Step 1: We have created an Apex Class named “LWC_ContactController” by which we will send the Contact record to Lightning Web Component. We can use the same class.

LWC_ContactController.cls

public with sharing class LWC_ContactController{
	@AuraEnabled
	public static Contact getImperativeStaticContact(){
		return [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 1];
	}
}

getImperativeStaticContact() method returns contact record. We have not set cacheable = true due to application of imperative mechanism.

Step 2: As per previous examples, we need to update the “showImperativeApexStaticContact.js-meta.xml” file to set the visibility in Lightning App Builder.

showImperativeApexStaticContact.js-meta.xml

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

Step 3: Need to write the respective HTML file.

showImperativeApexStaticContact.html

<template>
        <lightning-card title="Showing Static Record (Imperative * Apex)">            
            <lightning-layout> 
              <lightning-layout-item flexibility="auto" padding="around-small">
                   Contact
                   <template if:true={contactObj}> 
                        <div class="slds-m-around_medium">
                            <p>{name}</p>
                            <p>{phone}</p>
                            <p><lightning-formatted-email value={email}></lightning-formatted-email></p>
                        </div>
                    </template>
                    <template if:true={error}>
                        {error}>
                    </template>
              </lightning-layout-item>
            </lightning-layout>
        </lightning-card>
</template>

Step 4: Now, we need to work on the JS file.

showImperativeApexStaticContact.js

import { LightningElement, track } from 'lwc';
import { getSObjectValue } from '@salesforce/apex';
import getImperativeStaticContact from '@salesforce/apex/LWC_ContactController.getImperativeStaticContact';

import CONTACT_NAME_FIELD from '@salesforce/schema/Contact.Name';
import CONTACT_PHONE_FIELD from '@salesforce/schema/Contact.Phone';
import CONTACT_EMAIL_FIELD from '@salesforce/schema/Contact.Email';

export default class ShowImperativeApexStaticContact extends LightningElement {

    @track contactObj;
    @track error;

    connectedCallback(){
        getImperativeStaticContact()
        .then(result => {
            this.contactObj = result;
            this.error = undefined;
        }).catch(error=>{
            this.error = error;
            this.contactObj = undefined;
            
        })
    }
    

    get name(){
        return this.contactObj
            ? getSObjectValue(this.contactObj, CONTACT_NAME_FIELD)
            : '';
    }

    get phone(){
        return this.contactObj
            ? getSObjectValue(this.contactObj, CONTACT_PHONE_FIELD)
            : '';
    }

    get email(){
        return this.contactObj
            ? getSObjectValue(this.contactObj, CONTACT_EMAIL_FIELD)
            : '';
    }
}

In the imperative mechanism, we have set the contacts Private Reactive Property (during component creation time) to the contact record coming from the said Apex Class. Remaining process in same as wire mechanism.

Step 5: Need to add this component into Lightning App/Home or Record Page.

Result

8,583 total views, 9 views today

Apex Imperative Method with Parameters

Now, we will study how to get data based on some parameters from Lightning Platform Database using Imperative Way with Parameters in Lightning Web Component.

To do this exercise, we will show the Contact Records when user will click Search button after provided the Account Name.

Step 1: We have created an Apex Class named “LWC_ContactController” by which we will send the Contact record based on Account Name to Lightning Web Component. We can use the same class.

LWC_ContactController.cls

public with sharing class LWC_ContactController{
	@AuraEnabled
       public static List<Contact> searchImperativeContactList(String accountName){
           if (String.isBlank(accountName)) {
                return new List<Contact>();
            }
            String key = '%' + accountName + '%';
            return [SELECT Id, Name, Email FROM Contact WHERE Account.Name LIKE : key];
       }
}

searchImperativeContactList() method of the Apex Class “LWC_ContactController” returns the Contact Record based on Account Name. Please notice that we didn’t use cacheable = true for searchImperativeContactList() method just like wiring mechanism. That is the primary difference between wiring mechanism and imperative mechanism.

Step 2: After that, we have built a LWC named “showContactsIMP”. As per previous examples, we need to update the “showContactsIMP.js-meta.xml” file to set the visibility in Lightning App Builder.

showContactsIMP.js-meta.xml

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

Step 3: Need to write the respective HTML file.

showContactsWMP.html

<template>
    <lightning-card title="Apex Imperative Method With Parameters">            
        <lightning-layout>  
            <lightning-layout-item flexibility="auto" padding="around-small">        
                <lightning-layout-item flexibility="grow">
                    <lightning-input label="Enter Account Name" 
                                    type="search"  
                                    onchange={searchContact} 
                                    value={searchKey}>
                    </lightning-input>
                </lightning-layout-item>
                <lightning-layout-item class="slds-p-left_xx-small">
                    <lightning-button
                        label="Search"
                        onclick={doSearch}
                    ></lightning-button>
                </lightning-layout-item> 
                <lightning-layout-item class="slds-m-bottom_small">  
                    <template if:true={contacts}>                        
                        <template for:each={contacts} for:item="contact">                        
                            <p key={contact.Id}>                               
                                {contact.Name}
                            </p>
                        </template>
                    </template>
                    <template if:true={error}>
                        {error}>
                    </template>
                </lightning-layout-item>   
            </lightning-layout-item>              
        </lightning-layout>
      </lightning-card>
</template>

Step 4: Now, we need to work on the JS file.

showContactsIMP.js

import { LightningElement, track } from 'lwc';
import searchImperativeContactList from '@salesforce/apex/LWC_ContactController.searchImperativeContactList';


export default class ShowContactsIMP extends LightningElement {

    @track contacts;
    @track error;

    searchContact(event){        
        this.searchKey = event.target.value;        
    }

    doSearch() {
        searchImperativeContactList({ accountName: this.searchKey })
            .then(result => {
                this.contacts = result;
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                this.contacts = undefined;
            });
    }

}

As per the imperative mechanism writing rules, first we have imported “searchImperativeContactList” from the Apex Class, “LWC_ContactController”. We have built a function named “doSearch()” where the same adapter searchImperativeContactList() is invoked using javascript promise. We need to pass the parameter as Search Key/Account Name.Here, we don’t need to put ‘$’ sign before property during configuration of parameters. We have set the result to the respective reactive properties such as contacts and error.

We didn’t use cacheable = true for searchImperativeContactList() method as per imperative mechanism guide line.

Step 5: At last, need to add this LWC into Lightning App/Home or Record Page.

Result

77,643 total views, 21 views today