Skip to main content

Communication between Lightning Web Components. How many can we use?

About Us
Published by JET BI
13 November 2023
20

Introduction 

Communication between components is crucial to creating responsive and dynamic applications. There are different ways to communicate between Lightning Web Components (LWC), depending on the relationship between the components or event being communicated. For each method, we'll look at a really simple example, focusing on information that only applies to that specific method. By the end of this article, you will have a better understanding of how to communicate between LWC.
 

What are the ways to communicate between components in LWC?
 

There are 3 ways to communicate between components in LWC:

  • Parent-to-Child communication is used when the Parent component's HTML file includes a Child component and we need to pass data from the Parent component to the Child component or call a function in the Child component.
  • Child-to-Parent communication is used when we need to pass data from the Child component to the Parent component.
  • Communication between unrelated components is used to exchange data between components that don’t have a common parent component.
  1. Parent-to-Child communication

To enable Parent-to-Child communication, the child component must have a public property or function declared using the @api decorator.

Pass data to a Child property

child.js

import { LightningElement, api } from 'lwc';


export default class Child extends LightningElement {
  @api childVar;
}


child.html

<template>
</template>


parent.html

<template>
  <c-child child-var={parentVar}></c-child>
</template>


parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  parentVar = 'Hello!';
}

 

Call a Child function

To call a child function, it is necessary to take into account that this can only be done after the child's component has entered the DOM. So in this example I am using the renderedCallback method.

child.js

import { LightningElement, api } from 'lwc';


export default class Child extends LightningElement {
  @api
  childFunction() {
    return 'Hello!';
  }
}


child.html

<template>
</template>


parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  renderedCallback() {
    let childCmp = this.template.querySelector('c-child');
    let result = childCmp.childFunction();
  }
}


parent.html

<template>
<c-child></c-child>
</template>

 

          2. Child-to-Parent communication

The Child component cannot directly pass data to the Parent component using property, so this can be done by dispatching a custom event from the Child component, and the Parent component must listen for this event. 

Child-to-Parent

child.js

import { LightningElement } from 'lwc';


export default class Child extends LightningElement {
  renderedCallback() {
    this.childFunction();
  }


  childFunction() {
    this.dispatchEvent(new CustomEvent('childevent', {
      detail: {
        childVar: 'Hello!',
      }
    }));
  }
}


child.html

<template>
</template>

 

parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  parentFunction(event) {
    let result = event.detail.childVar;
  }
}


parent.html

<template>
  <c-child onchildevent={parentFunction}></c-child>
</template>

 

Child-to-Grandparent

When we have a chain of nested components, we often need to pass data from a child component to the grandparent component. So we need to configure Event Propagation using the bubbles property set to true in dispatchEvent on the intermediate components (in our case, it is the Parent component).

child.js

import { LightningElement } from 'lwc';


export default class Child extends LightningElement {
  renderedCallback() {
    this.childFunction();
  }


  childFunction() {
    this.dispatchEvent(new CustomEvent('childevent', {
      detail: {
        childVar: 'Hello!',
      }
    }));
  }
}


child.html

<template>
</template>


parent.js

import { LightningElement } from 'lwc';


export default class Parent extends LightningElement {
  parentFunction(event) {
    this.dispatchEvent(new CustomEvent('parentevent', {
      bubbles: true,
      detail: event.detail
    }));
  }
}


parent.html

<template>
  <c-child onchildevent={parentFunction}></c-child>
</template>

 

grandparent.js

import { LightningElement } from 'lwc';


export default class Grandparent extends LightningElement {
  grandparentFunction(event) {
    let result = event.detail.childVar;
  }
}


grandparent.html

<template>
  <c-parent onparentevent={grandparentFunction}></c-parent>
</template>

 

3. Communication between unrelated components

To communicate between unrelated components Lightning Message Service (LMS) should be used. LMS is a publish and subscribe (pub-sub) service.

First of all, create a Message Channel. To do this, create a messageChannels folder in your project in VSCode. In the folder, create MyMessageChannel.messageChannel-meta.xml file with the content below and deploy it to your org.

MyMessageChannel.messageChannel-meta.xml

<?xml version="1.0" encoding="UTF-8" ?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
  <masterLabel>MyMessageChannel</masterLabel>
  <isExposed>true</isExposed>
  <description>Sends messages to unrelated components</description>
  <lightningMessageFields>
    <fieldName>value</fieldName>
    <description>The value to send to a component</description>
  </lightningMessageFields>
</LightningMessageChannel>

 

Then create 2 unrelated components. The first has an input field and publishes value from the field via the Message Channel. The second subscribes to this Message Channel and displays the value.

component1.html

<template>
  <lightning-input onchange={sendMessage}></lightning-input>
</template>


component1.js

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import MY_MESSAGE_CHANNEL from '@salesforce/messageChannel/MyMessageChannel__c';


export default class Component1 extends LightningElement {
  @wire(MessageContext)
  messageContext;


  sendMessage(event) {
    const payload = {
      value: event.target.value,
    };
    publish(this.messageContext, MY_MESSAGE_CHANNEL, payload);
  }
}


component2.html

<template>
  <p>{value}</p>
</template>

 

component2.js

import { LightningElement, wire } from 'lwc';
import { subscribe, MessageContext } from 'lightning/messageService';
import MY_MESSAGE_CHANNEL from '@salesforce/messageChannel/MyMessageChannel__c';


export default class Component1 extends LightningElement {
  value;
  subscription;


  @wire(MessageContext)
  messageContext;


  connectedCallback() {
    this.subscribeToMessageChannel();
  }


  subscribeToMessageChannel() {
    this.subscription = subscribe(
      this.messageContext,
      MY_MESSAGE_CHANNEL,
      (message) => this.handleMessage(message)
    );
  }


  handleMessage(message) {
    this.value = message.value;
  }
}

 

Conclusion

We've covered Parent-to-Child, Child-to-Parent and unrelated components communications. I hope the examples above have helped you gain a clearer understanding of how to communicate between Lightning Web Components.

If you need any help, don’t hesitate to contact us. Leave a request and we will help you!


Egor Glyakov
Salesforce Developer
image
Expertise
Question to the expert
image

We have available resources to start working on your project within 5 business days

1 UX Designer

image

1 Admin

image

2 QA engineers

image

1 Consultant

image
Related Articles
All articles
image
Practical Salesforce features for HR analytics
Today, we would like to show you what important HR metrics you can track in reports and dashboards on the Salesforce platform for your practical HR Management and HR Analytics. With Salesforce's highly customizable nature, you can create automated standard and customized HR reports and get insights and statistics about every aspect of your HR processes.
28 November 2023
image
Exploring 32 advanced resource capacity and planning apps for small and medium size businesses
In the dynamic landscape of modern business, effective resource capacity and planning play pivotal roles in ensuring the streamlined operation and growth of small and medium-sized enterprises (SMEs). The demand for advanced tools that facilitate optimal resource utilization, strategic planning, and seamless collaboration has led to the emergence of a myriad of applications designed to cater to the unique needs of smaller businesses.
27 November 2023
image
What is better for business: to try new investments into “booming software” or get the most of the investments you’ve already made?
Are you unsure whether to invest in new software or maximize the value of your existing investments? This is a question that many businesses grapple with. On one hand, investing in new software can provide innovative solutions and keep your business ahead of the competition. On the other hand, optimizing your current investments can help you fully utilize the resources you already have.
08 November 2023