Lightning Web Component Event Handling – Pub Sub

Share on facebook
Share on twitter
Share on linkedin
The Publish-Subscribe pattern/model is same as Application Event in Lighting Component. If you want to communicate between components those are not bounding in parent child relationship, but available in same page (say, in same app-builder page), then we will use publish-subscribe pattern. Here Salesforce already publish a pubsub.js file which we will use. 
  1. The Publish-Subscribe pattern/model is same as Application Event in Lighting Component. If you want to communicate between components those are not bounding in parent child relationship, but available in same page (say, in same app-builder page), then we will use publish-subscribe pattern. Here Salesforce already publish a pubsub.js file which we will use. 

/** 

 * A basic pub-sub mechanism for sibling component communication 

 * 

 */ 

const events = {}; 

const samePageRef = (pageRef1, pageRef2) => { 

    const obj1 = pageRef1.attributes; 

    const obj2 = pageRef2.attributes; 

    return Object.keys(obj1) 

        .concat(Object.keys(obj2)) 

        .every(key => { 

            return obj1[key] === obj2[key]; 

        }); 

}; 

/** 

 * Registers a callback for an event 

 * @param {string} eventName – Name of the event to listen for. 

 * @param {function} callback – Function to invoke when said event is fired. 

 * @param {object} thisArg – The value to be passed as the this parameter to the callback function is bound. 

 */ 

const registerListener = (eventName, callback, thisArg) => { 

    // Checking that the listener has a pageRef property. We rely on that property for filtering purpose in fireEvent() 

    if (!thisArg.pageRef) { 

        throw new Error( 

            ‘pubsub listeners need a “@wire(CurrentPageReference) pageRef” property’ 

        ); 

    } 

    if (!events[eventName]) { 

        events[eventName] = []; 

    } 

    const duplicate = events[eventName].find(listener => { 

        return listener.callback === callback && listener.thisArg === thisArg; 

    }); 

    if (!duplicate) { 

        events[eventName].push({ callback, thisArg }); 

    } 

}; 

/** 

 * Unregisters a callback for an event 

 * @param {string} eventName – Name of the event to unregister from. 

 * @param {function} callback – Function to unregister. 

 * @param {object} thisArg – The value to be passed as the this parameter to the callback function is bound. 

 */ 

const unregisterListener = (eventName, callback, thisArg) => { 

    if (events[eventName]) { 

        events[eventName] = events[eventName].filter( 

            listener => 

                listener.callback !== callback || listener.thisArg !== thisArg 

        ); 

    } 

}; 

/** 

 * Unregisters all event listeners bound to an object. 

 * @param {object} thisArg – All the callbacks bound to this object will be removed. 

 */ 

const unregisterAllListeners = thisArg => { 

    Object.keys(events).forEach(eventName => { 

        events[eventName] = events[eventName].filter( 

            listener => listener.thisArg !== thisArg 

        ); 

    }); 

}; 

/** 

 * Fires an event to listeners. 

 * @param {object} pageRef – Reference of the page that represents the event scope. 

 * @param {string} eventName – Name of the event to fire. 

 * @param {*} payload – Payload of the event to fire. 

 */ 

const fireEvent = (pageRef, eventName, payload) => { 

    if (events[eventName]) { 

        const listeners = events[eventName]; 

        listeners.forEach(listener => { 

            if (samePageRef(pageRef, listener.thisArg.pageRef)) { 

                try { 

                    listener.callback.call(listener.thisArg, payload); 

                } catch (error) { 

                    // fail silently 

                } 

            } 

        }); 

    } 

}; 

export { 

    registerListener, 

    unregisterListener, 

    unregisterAllListeners, 

    fireEvent 

}; 

  1. Now, we have to create two more components,;one will be used to publish an event and another will be used to subscribe the event. Say, our publisher component name is myPublisher and our subscriber component is mySubscriber. 

3.  ************* Publisher Component Details. ************* 

myPublisher.html  

<template> 

    <lightning-card title=”Publisher Component”> 

        <lightning-layout> 

            <lightning-layout-item> 

                <button onclick={displayLabradorDetails}>Labrador</button> 

            </lightning-layout-item> 

        </lightning-layout> 

    </lightning-card> 

</template> 

myPublisher.js   

import { LightningElement, wire } from ‘lwc’; 

import { CurrentPageReference } from ‘lightning/navigation’; 

import { fireEvent } from ‘c/pubsub’; 

export default class MyPublisher extends LightningElement { 

    @wire(CurrentPageReference) pageRef; 

    displayLabradorDetails(){ 

        fireEvent(this.pageRef, “eventdetails”, “Breed – Labrador”); 

    } 

myPublisher.js-meta.xml 

<?xml version=”1.0″ encoding=”UTF-8″?> 

<LightningComponentBundle xmlns=”http://soap.sforce.com/2006/04/metadata” fqn=”myPublisher”> 

    <apiVersion>45.0</apiVersion> 

    <isExposed>true</isExposed> 

    <targets> 

        <target>lightning__AppPage</target> 

        <target>lightning__RecordPage</target> 

        <target>lightning__HomePage</target>    

    </targets> 

</LightningComponentBundle> 

4.  ************* Subscriber Component Details. ************* 

mySubscriber.html 

<template> 

    <lightning-card title=”Subscriber Component”> 

        <lightning-layout> 

            <lightning-layout-item> 

                {details} 

            </lightning-layout-item> 

        </lightning-layout> 

    </lightning-card> 

</template> 

mySubscriber.js 

import { LightningElement, track, wire } from ‘lwc’; 

import { registerListener, unregisterAllListeners } from ‘c/pubsub’; 

import { CurrentPageReference } from ‘lightning/navigation’; 

export default class MySubscriber extends LightningElement { 

    @track details; 

    @wire(CurrentPageReference) pageRef; 

    connectedCallback() { 

        registerListener(“eventdetails”, this.sutUpDetails, this); 

    } 

    disconnectedCallback() { 

        unregisterAllListeners(this); 

    } 

    sutUpDetails(dogDtl){ 

        this.details = dogDtl; 

    } 

mySubscriber.js-meta.xml 

<?xml version=”1.0″ encoding=”UTF-8″?> 

<LightningComponentBundle xmlns=”http://soap.sforce.com/2006/04/metadata” fqn=”mySubscriber”> 

    <apiVersion>45.0</apiVersion> 

    <isExposed>true</isExposed> 

    <targets> 

        <target>lightning__AppPage</target> 

        <target>lightning__RecordPage</target> 

        <target>lightning__HomePage</target>    

    </targets> 

</LightningComponentBundle> 

5. Now, authorize your Org and then deploy all above 3 LWC components in your authorized Org. Fnally, drag myPublisher and mySubscriber in your Lightning Page. 

 

Reference link:

https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.html

  

   

About MST

At MST Solutions our cornerstone is to adapt, engage and create solutions which guarantee the success of our clients. The talent of our team and experiences in varied business verticals gives us an advantage over other competitors.

Recent Articles

Work with us.

Our people aren’t just employees, they are key to the success of our business. We recognize the strengths of each individual and allow them time and resources to further develop those skills, crafting a culture of leaders who are passionate about where they are going within our organization.