New Batch#100 (10th Nov 2021) - Salesforce Admin + Dev Training (WhatsApp: +91 - 8087988044) :https://t.co/p4F3oeQagK

Monday, 22 June 2020

LWC Cheat Sheet


Wire

@wire with uiRecordApi API -
===============================
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';
export default class Record extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: [ACCOUNT_NAME_FIELD] })
record;
}
---
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
export default class Record extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: ['Account.Name'] })
record;
}
---
// wireGetRecordDynamicContact.js
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
const FIELDS = [
'Contact.Name',
'Contact.Title',
'Contact.Phone',
'Contact.Email',
];
export default class WireGetRecordDynamicContact extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: FIELDS })
contact;
get name() {
return this.contact.data.fields.Name.value;
}
get title() {
return this.contact.data.fields.Title.value;
}
get phone() {
return this.contact.data.fields.Phone.value;
}
get email() {
return this.contact.data.fields.Email.value;
}
}
----
// wireFunction.js
import { LightningElement, api, track, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
export default class WireFunction extends LightningElement {
@api recordId;
@track record;
@track error;
@wire(getRecord, { recordId: '$recordId', fields: ['Account.Name'] })
wiredAccount({ error, data }) {
if (data) {
this.record = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.record = undefined;
}
}
get name() {
return this.record.fields.Name.value;
}
}
----
@wire with Apex Method -
========================
public with sharing class ContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> getContactList() {
return [
SELECT Id, Name, Title, Phone, Email, Picture__c
FROM Contact
WHERE Picture__c != null
WITH SECURITY_ENFORCED
LIMIT 10
];
}
@AuraEnabled(cacheable=true)
public static List<Contact> findContacts(String searchKey) {
String key = '%' + searchKey + '%';
return [
SELECT Id, Name, Title, Phone, Email, Picture__c
FROM Contact
WHERE Name LIKE :key AND Picture__c != null
WITH SECURITY_ENFORCED
LIMIT 10
];
}
@AuraEnabled(cacheable=true)
public static Contact getSingleContact() {
return [
SELECT Id, Name, Title, Phone, Email, Picture__c
FROM Contact
WITH SECURITY_ENFORCED
LIMIT 1
];
}
}
----------
import { LightningElement, wire } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class ApexWireMethodToProperty extends LightningElement {
@wire(getContactList) contacts;
}
-----------
import { LightningElement, wire } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class ApexWireMethodToFunction extends LightningElement {
contacts;
error;
@wire(getContactList)
wiredContacts({ error, data }) {
if (data) {
this.contacts = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.contacts = undefined;
}
}
}
--------
searchKey = '';
@wire(findContacts, { searchKey: '$searchKey' })
contacts;
----------------
Passing Multiple Parameters @wire -
@wire(getContacts, {accId:'$recordId', value: '$value' }) contacts;
view raw wire hosted with ❤ by GitHub

JavaScript Find method -

var age = 17;
function myFunction() {
  document.getElementById("demo").innerHTML = ages.find(ageVal => {
   return ageVal >= age;
  });
}

Calling child LWC method from parent -

const child = this.template.querySelector('c-public-method-child');
console.log(JSON.stringify(child));
child.changeSelection(this.city);

Constructor should have super in LWC js -

constructor() {
 super();
 console.log('Parent > Constructor.');
}

Importing and rendering multiple templates in LWC js -

import template1 from './lifecycleChild.html';
import template2 from './template2.html';
render() {
 console.log('Child > render.');
 return this.showTemplate2 ? template2 : template2;
}

CustomEvent firing from child to the parent

//Firing the event from the child component 
var cusEvt = new CustomEvent('mychildevent',{detail:'I am the message from child to parent.',bubbles:true});
this.dispatchEvent(cusEvt);

//Approach1: Handling the event from parent UI -
[c-child onmychildevent={handleChildEvent}][/c-child]
Note: handleChildEvent is the method in parent
handleChildEvent(event) { console.log(event.detail); }

//Approach2: Handling the event from parent JS -
constructor() {
 super();
 console.log('constructor');
 this.template.addEventListener('mychildevent',this.handleChildEvent.bind(this));
}
Note: When addEventListener is used "bubble:true" should be there in CustomEvent

Pubsub: Application Event Handling -

Download pubsub repository.

Firing the event -

  import {fireEvent} from 'c/pubsub';
  import { CurrentPageReference } from 'lightning/navigation';

  @wire(CurrentPageReference) 
  pageRef;
  
  handleClick() {
   debugger;
   fireEvent(this.pageRef,'parent2event','I am the event firing from parent2 component.');
   //Note: Event Name should be all in small characters and should not have special characters
  }
 

Handling the event -

  import {registerListener,unregisterAllListeners} from 'c/pubsub';
  import { CurrentPageReference } from 'lightning/navigation';
  
  @wire(CurrentPageReference) 
  pageRef;
  
  connectedCallback() {
   console.log('connectedCallback');
   registerListener('parent2event',this.handleAppEvent,this);
  }
  disconnectedCallback() {
   console.log('disconnectedCallback');
   unregisterAllListeners(this);
  }
  handleAppEvent(payload) {
   console.log('***payload: '+payload);
  }
 

Reusable javaScript -

Utility.js -

  const add = function(num1,num2) {
   return num1 + num2;
  }
  const substract = function(num1,num2) {
   return num1 - num2;
  }
  const multiply = function(num1,num2) {
   return num1 * num2;
  }
  const divide = function(num1,num2) {
   return num1 / num2;
  }

  export {
   add,
   substract,
   multiply,
   divide
  }
 

calling reusable js functions -

  import {add,substract,multiply,divide} from 'c/utility';
  
  constructor() {
   super();
   console.log('add: ',add(200,100));
   console.log('sub: ',substract(200,100));
   console.log('mul: ',multiply(200,100));
   console.log(`Div: ${divide(200,100)}`);
  }
 

LDS to get and create records -

  import { LightningElement, track, wire } from 'lwc';
  import {createRecord,getRecord} from 'lightning/uiRecordApi'

  const fieldsArray = ['Contact.FirstName','Contact.LastName','Contact.Email','Contact.MobilePhone'];
  export default class ContactForm extends LightningElement {   

   @track recordId;

   @wire(getRecord,{recordId:"$recordId", fields: fieldsArray})
   contact;


   firstNameChangeHandler(event) {
    this.firstName = event.target.value;
   }
   lastNameChangeHandler(event) {
    this.lastName = event.target.value;
   }
   emailChangeHandler(event) {
    this.email = event.target.value;
   }
   mobileChangeHandler(event) {
    this.mobile = event.target.value;
   }
   
   createContact() {
    debugger;
    //Field API Names along with the data
    const fields = {
     "FirstName" : this.firstName,
     "LastName" : this.lastName,
     "Email" : this.email,
     "MobilePhone" : this.mobile
    };

    var recordInput = {
     apiName : "Contact", fields
    };
     
    //Using javaScript promise concept
    createRecord(recordInput).then(response => {
     console.log('Record Id: '+response.id);
     this.recordId = response.id;
    }).catch(error => {
     console.log('Error Object: '+JSON.stringify(error));
     console.log('Error Message: '+error.body.message);
    });

   }

   get retFirstName() {
    debugger;
    console.log('contact: '+JSON.stringify(this.contact));
    if(this.contact.data) {
     return this.contact.data.fields.FirstName.value;
    }
    return undefined;
   }

   get retLastName() {
    debugger;
    if(this.contact.data) {
     return this.contact.data.fields.LastName.value;
    }
    return undefined;
   }

   get retEmail() {
    debugger;
    if(this.contact.data) {
     return this.contact.data.fields.Email.value;
    }
    return undefined;
   }

   get retMobile() {
    debugger;
    if(this.contact.data) {
     return this.contact.data.fields.MobilePhone.value;
    }
    return undefined;
   }
   
   
  }
 

Imperative Apex Call, Toast Message and Navigation Service

Apex Class -
public with sharing class ApexCallwithWireServiceCtrl {
@AuraEnabled(cacheable=true)
public static List<Account> getAccs(String rating){
return [select Id, Name, Industry, Rating from Account where Rating =: rating];
}
@AuraEnabled
public static Map<String,Object> getCons(Map<String,Object> inputMap){
Map<String,Object> outputMap = new Map<String,Object>();
outputMap.put('contacts',[select Id, FirstName, LastName, Email from Contact]);
return outputMap;
}
@AuraEnabled
public static string deleteRow(String recordId){
system.debug('recordId: '+recordId);
String msg;
try {
delete [select Id from Contact where Id =: recordId];
msg = 'Record has been deleted';
}
catch(Exception e) {
msg = 'Exception: '+e.getMessage();
}
return msg;
}
}
Js -
import { LightningElement, track } from 'lwc';
import getCons from '@salesforce/apex/ApexCallwithWireServiceCtrl.getCons';
import deleteRow from '@salesforce/apex/ApexCallwithWireServiceCtrl.deleteRow';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { NavigationMixin } from 'lightning/navigation';
import Srinusfdc_Logo from '@salesforce/resourceUrl/Srinusfdc_Logo';
const columns = [
{ label: 'First Name', fieldName: 'FirstName' },
{ label: 'Last Name', fieldName: 'LastName'},
{ label: 'Email', fieldName: 'Email'}
];
export default class ImperativeApexCall extends NavigationMixin(LightningElement) {
@track data;
@track columns = columns;
@track error;
@track recordPageUrl;
@track url = Srinusfdc_Logo;
constructor() {
super();
this.getData();
}
getData() {
const inputMap = {};
getCons({inputMap : inputMap}).then(data => {
console.log('data: '+JSON.stringify(data));
this.data = data.contacts;
}).catch(error => {
error = this.error;
});
}
navigateToObjectHome() {
// Navigate to the Account home page
this[NavigationMixin.Navigate]({
type: 'standard__objectPage',
attributes: {
objectApiName: 'Contact',
actionName: 'home',
},
});
}
navigateToRecordPage(event) {
debugger;
const recId = event.target.id;
const paramArray = recId.split("-");
this[NavigationMixin.GenerateUrl]({
type: 'standard__recordPage',
attributes: {
recordId: paramArray[0],
actionName: 'view',
},
}).then(url => {
this.recordPageUrl = url;
});
}
handleDelete(event) {
const recId = event.target.title;
deleteRow({recordId:recId}).then(result => {
console.log(`Success Msg form Server: ${result}`);
this.getData();
const evt = new ShowToastEvent({
title: 'Delete Success.',
message: result,
variant: 'success',
});
this.dispatchEvent(evt);
this.navigateToObjectHome();
}).catch(error => {
console.log(`Error Msg form Server: ${error}`);
const evt = new ShowToastEvent({
title: 'Delete Success.',
message: error,
variant: 'success',
});
this.dispatchEvent(evt);
});
}
}
Template -
<template>
<img src={url}></image>
<table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset">
<th class="" scope="col">
<div class="slds-truncate" title="First Name">First Name</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Last Name">Last Name</div>
</th>
<th class="" scope="col">
<div class="slds-truncate" title="Email">Email</div>
</th>
</tr>
</thead>
<tbody>
<template for:each={data} for:item="row" for:index="index">
<tr class="slds-hint-parent" key={row.Id}>
<th data-label="Opportunity Name" scope="row">
<div class="slds-truncate" title={row.FirstName}>
<a href={recordPageUrl} onclick={navigateToRecordPage} tabindex="-1" id={row.Id}>{row.FirstName}</a>
</div>
</th>
<td data-label="Account Name">
<div class="slds-truncate" title={row.LastName}>{row.LastName}</div>
</td>
<td data-label="Close Date">
<div class="slds-truncate" title={row.Email}>{row.Email}</div>
</td>
<td>
<lightning-button variant="destructive" label="Delete" title={row.Id} onclick={handleDelete} class="slds-m-left_x-small"></lightning-button>
</td>
</tr>
</template>
</tbody>
</table>
</template>