Lightning Web Components: All Directions of Communication
In a past article I provided an example of how to communicate between unrelated Lightning Web Components.
Here I have refactored the system to demonstrate all-directional lightning web component communication
- Passing data between unrelated components
- Passing data from parent to child
- Passing data from child to parent
ping and pong lwc are now only a handful of lines long
ping and pong html
Bottom-up messaging
Attributes that start with on___ indicate an event from the child. We set the value to the name of the method we want the event to invoke.
Top-down messaging
We can set variables from parent to child, the “source” attribute represents the “source” local variable of the child component. So in this one tag, c-ping-pong-messenger, we demonstrate both directions of parent-child messaging.
ping.html
<template>
<p>{value}!</p>
<c-ping-pong-messenger onnewmessage={newMessage} source=ping read=pong></c-ping-pong-messenger>
</template>
pong.html
<template>
<p>{value}!</p>
<c-ping-pong-messenger onnewmessage={newMessage} source=pong read=ping></c-ping-pong-messenger>
</template>
ping.js
import { LightningElement } from 'lwc';
export default class Ping extends LightningElement {
value = 'Pong Value...';
newMessage(event){
this.value = event.detail;
}
}
pong.js
import { LightningElement } from 'lwc';
export default class Pong extends LightningElement {
value = 'Ping Value...';
newMessage(event){
this.value = event.detail;
}
}
ping and pong now share the same child component, pingPongMessenger
pingPongMessenger.html
<template>
<lightning-input onchange={sendMessage}></lightning-input>
</template>
pingPongMessenger.js
import { LightningElement, wire, api } from 'lwc';
import { publish, subscribe, MessageContext } from 'lightning/messageService';
import PING_PONG_CHANNEL from '@salesforce/messageChannel/Ping_Pong__c';export default class PingPongMessenger extends LightningElement {
@api source = '';
@api read = '';
subscription = null;
@wire(MessageContext)
messageContext;
sendMessage(event) {
const payload = {
value: event.target.value,
source: this.source
};
publish(this.messageContext, PING_PONG_CHANNEL, payload);
}
subscribeToMessageChannel() {
this.subscription = subscribe(
this.messageContext,
PING_PONG_CHANNEL,
(message) => this.handleMessage(message)
);
}
handleMessage(message) {
if (message.source == this.read){
const messageEvent = new CustomEvent("newmessage",{
detail: message.value
});
this.dispatchEvent(messageEvent);
}
}
connectedCallback() {
this.subscribeToMessageChannel();
}
}