Tuesday, June 25, 2019

Communicate b/w Parent-Child Component using LWC

    What is Event in LWC?
  • Events in Lightning web components are built on DOM Events, a collection of APIs and objects available in every browser.
  • Lightning web components dispatch standard DOM events.

Some different types of web events :

  • Mouse event : example - mousedown, mouseup, click, dblclick
  • Touch event: example - touchstart, touchmove
  • Keyboard event : example -keydown, keypress, keyup
  • Form event: example -focus, blur, change, submit
  • Window event :example - scroll, resize, hashchange, load, unload

Let us discuss here how to use the lightning web component events to communicate between components.

How to  create events, using the CustomEvent interface and dispatch an event in lwc?
To create an event, use the CustomEvent() constructor.
 Example  : this.dispatchEvent(new CustomEvent('myTxt'));
 Note : CustomEvent constructor has one required parameter which is string that denotes event type.

 To dispatch an event, call the EventTarget.dispatchEvent() method.
where EventTarget is a DOM interface implemented by objects that can receive events and may have listeners for them.
  • EventTarget.addEventListener()
        Registers an event handler of a specific event type on the EventTarget.

  • EventTarget.removeEventListener()
         Removes an event listener from the EventTarget.

  • EventTarget.dispatchEvent()
       Dispatches an event to this EventTarget


Here is my sample lwc receipe. It divided into 3 sections: 
  1. Basic form to add the contact detail (on adding the record it will refresh the contact list records)
  2. Show the list of contact records
  3. Show the contact details.


 Basically in the receipe I have created 2 main component and apex class(Parent - child).
1. ContactListContainer - this is my parent component.
2. Add contact and contactList is my child component.
3. Apex class
Here I will add the contact detail in the list of contact records without refreshing the page(Using refreshApex here) and on clicking the contact record it will further show the contact full detail.

Check the video of this sample recipe. Its time to code in lwc :



contactListContainer.html
<template>
<lightning-layout>
<lightning-layout-item flexibility="auto" padding="horizontal-medium" style="width:50%;">
<c-add-contact onaddcontact={addContactHandler}></c-add-contact>
</lightning-layout-item>
<lightning-layout-item flexibility="auto" padding="horizontal-medium" style="width:50%;">
<lightning-card title="List of Contact Records" icon-name="standard:groups" if:true={conList.data}>
<template for:each={conList.data} for:item="con">
<c-contact-list key={con.Id} contact={con} onselected={handleSelectedContact}></c-contact-list>
</template>
<template if:true={conList.error}>
<div>no data available</div>>
</template>
</lightning-card>
</lightning-layout-item>
<lightning-layout-item flexibility="auto" padding="horizontal-medium" style="width:50%;">
<lightning-card icon-name="standard:contact" if:true={selectedContact} >
<p class="slds-truncate">Name : {selectedContact.Name}</p>
<p class="slds-truncate">Email : {selectedContact.Email}</p>
<p class="slds-truncate">Phone No : {selectedContact.Phone}</p>
</lightning-card>
</lightning-layout-item>
</lightning-layout>
</template>
contactListContainer.js
import { LightningElement, wire, track } from 'lwc';
import getContactList from '@salesforce/apex/addNewContact.getContactList';
import { refreshApex } from '@salesforce/apex';
export default class ContactListContainer extends LightningElement {
@track selectedContact;
@wire(getContactList) conList;
addContactHandler() {
refreshApex(this.conList);
}
handleSelectedContact(event) {
const contactId = event.detail;
this.selectedContact = this.conList.data.find(contact => contact.Id === contactId);
//Console.log('@@selectedContact==' +JSON.stringify(this.selectedContact));
}
}

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


addContact.html
<template>
<lightning-card title="Add Contact detail" icon-name="standard:contact">
<div class="slds-p-horizontal_small">
<div class="slds-media__body" >
<lightning-input label="FirstName" type="text" value={fname} onchange={fnamechange}></lightning-input>
<lightning-input label="LastName" type="text" value={lname} onchange={lnamechange}></lightning-input>
<lightning-input label="Email" type="Email" value={email} onchange={emailchange}></lightning-input>
<lightning-input label="Phone Number" type="text" value={phoneNo} onchange={phoneNochange}></lightning-input>
<div>
<lightning-button label="Submit" onclick={submitContactDetails}> </lightning-button>
</div>
</div>
</div>
</lightning-card>
</template>
view raw addContact.html hosted with ❤ by GitHub
addContact.js
import { LightningElement,track } from 'lwc';
import saveDetails from '@salesforce/apex/addNewContact.myContactDetails';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
export default class MyContactList extends LightningElement {
@track fname;
@track lname;
@track email;
@track phoneNo;
@track error;
fnamechange(event){
this.fname = event.target.value;
}
lnamechange(event){
this.lname = event.target.value;
}
emailchange(event){
this.email = event.target.value;
}
phoneNochange(event){
this.phoneNo = event.target.value;
}
submitContactDetails()
{
saveDetails({
fname: this.fname,
lname: this.lname,
email:this.email,
phoneNo:this.phoneNo
})
.then(result => {
this.fname ='';
this.lname = '';
this.email = '';
this.phoneNo = '';
this.dispatchEvent(new ShowToastEvent({
title: 'success',
message:result+'Contact created successfully. ',
variant: 'success'
}));
const saveConEvent = new CustomEvent('addcontact');
this.dispatchEvent(saveConEvent);
})
.catch(error =>{
this.error = error;
})
}
}
view raw addContact.js hosted with ❤ by GitHub
addContact.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="addContact">
<apiVersion>45.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>


contactList.html
<template>
<a href="#" onclick={handleSelectedContact}>
<div class="slds-p-around_medium lgc-bg">
<lightning-tile type="media" label={contact.Name}>
<lightning-icon slot="media" icon-name="standard:contact" ></lightning-icon>
<p class="slds-truncate">
<lightning-formatted-email value={contact.Email}></lightning-formatted-email>
</p>
</lightning-tile>
</div>
</a>
</template>

contactList.js
import { LightningElement,api } from 'lwc';
export default class ContactList extends LightningElement {
@api contact;
handleSelectedContact(event){
event.preventDefault();
const selectEvent = new CustomEvent('selected',{detail:this.contact.Id});
this.dispatchEvent(selectEvent);
}
}
view raw contactList.js hosted with ❤ by GitHub

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


Apex Class: addNewContact.cls
public with sharing class addNewContact {
@AuraEnabled(cacheable=true)
public static list<Contact> getContactList(){
list<Contact> conList = [select Id,Name,FirstName,LastName,Phone,Email from Contact Order by CreatedDate Desc];
return conList;
}
@AuraEnabled
public static String myContactDetails(String fname,String lname,String email,String phoneNo){
Contact con = new Contact();
con.firstname = fname;
con.lastname = lname;
con.Email = email;
con.Phone = phoneNo;
insert con;
return con.firstname;
}
}


Happy Learning :) .Please share your views and suggestions.

2 comments: