November 10, 2020

Subscribe and show PushTopic events notifications using Lightning Web Component

Sample Push Topic:

  1. PushTopic pushTopic = new PushTopic();  
  2. pushTopic.Name = 'AccountUpdates';  
  3. pushTopic.Query = 'SELECT Id, Name, Phone FROM Account WHERE BillingCity=\'San Francisco\'';  
  4. pushTopic.ApiVersion = 48.0;  
  5. insert pushTopic; 

Sample LWC:

HTLML:


  1. <template>  
  2.   
  3.     <lightning-card title="EmpApi Example" icon-name="custom:custom14">  
  4.   
  5.         <div class="slds-m-around_medium">  
  6.   
  7.             <p>Use the buttons below to Subscribe and Unsubscribe!!!</p>  
  8.             <lightning-input label="Channel Name" value={channelName}  
  9.                              onchange={handleChannelName}></lightning-input><br/>  
  10.             <lightning-button variant="success" label="Subscribe" title="Subscribe"  
  11.                               onclick={handleSubscribe} disabled={isSubscribeDisabled}  
  12.                               class="slds-m-left_x-small"></lightning-button>  
  13.             <lightning-button variant="destructive" label="Unsubscribe" title="Unsubscribe"  
  14.                               onclick={handleUnsubscribe} disabled={isUnsubscribeDisabled}  
  15.                               class="slds-m-left_x-small"></lightning-button><br/><br/>  
  16.             <b>Response:</b> <br/>{strResponse}  
  17.   
  18.         </div>  
  19.   
  20.     </lightning-card>  
  21.   
  22. </template

JS:

  1. import { LightningElement, track } from 'lwc';  
  2. import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled } from 'lightning/empApi';  
  3.   
  4. export default class PushTopicLWC extends LightningElement {  
  5.   
  6.     @track channelName = '/topic/AccountUpdates';  
  7.     @track isSubscribeDisabled = false;  
  8.     @track isUnsubscribeDisabled = !this.isSubscribeDisabled;  
  9.     @track strResponse = '';  
  10.   
  11.     subscription = {};  
  12.   
  13.     // Tracks changes to channelName text field  
  14.     handleChannelName(event) {  
  15.         this.channelName = event.target.value;  
  16.     }  
  17.   
  18.     // Handles subscribe button click  
  19.     handleSubscribe() {  
  20.         // Callback invoked whenever a new event message is received  
  21.         const messageCallback = ( response ) => {  
  22.             console.log( 'New message received : ', JSON.stringify( response ) );  
  23.             // Response contains the payload of the new message received  
  24.             this.strResponse = JSON.stringify( response );  
  25.             console.log( this.strResponse );  
  26.         };  
  27.   
  28.         // Invoke subscribe method of empApi. Pass reference to messageCallback  
  29.         subscribe( this.channelName, -1, messageCallback ).then(response => {  
  30.             // Response contains the subscription information on successful subscribe call  
  31.             console.log( 'Successfully subscribed to : ', JSON.stringify( response.channel ) );  
  32.             this.subscription = response;  
  33.             this.toggleSubscribeButton( true );  
  34.         });  
  35.     }  
  36.   
  37.     // Handles unsubscribe button click  
  38.     handleUnsubscribe() {  
  39.         this.toggleSubscribeButton( false );  
  40.   
  41.         // Invoke unsubscribe method of empApi  
  42.         unsubscribe(this.subscription, response => {  
  43.             console.log( 'unsubscribe() response: ', JSON.stringify( response ) );  
  44.             // Response is true for successful unsubscribe  
  45.         });  
  46.     }  
  47.   
  48.     toggleSubscribeButton( enableSubscribe ) {  
  49.   
  50.         this.isSubscribeDisabled = enableSubscribe;  
  51.         this.isUnsubscribeDisabled = !enableSubscribe;  
  52.   
  53.     }  
  54.   
  55.     registerErrorListener() {  
  56.   
  57.         // Invoke onError empApi method  
  58.         onError(error => {  
  59.             console.log( 'Received error from server: ', JSON.stringify( error ) );  
  60.             // Error contains the server-side error  
  61.         });  
  62.   
  63.     }  
  64.   

JS-Meta.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">  
  3.     <apiVersion>48.0</apiVersion>  
  4.     <isExposed>true</isExposed>        
  5.     <targets>      
  6.         <target>lightning__Tab</target>      
  7.     </targets>  
  8. </LightningComponentBundle> 

Output:



5 comments:

  1. Hi, I'm replicating this functionality and received the following error in subscription method:

    TypeError: Method Promise.prototype.then called on incompatible receiver [object Object]
    at Proxy.then ()
    at nr.apply (aura_prod.js:37)
    at c.handleSubscribe (empApiPoc.js:4)
    at callHook (aura_prod.js:37)
    at aura_prod.js:12
    at di (aura_prod.js:12)
    at Lo (aura_prod.js:12)
    at aura_prod.js:12
    at aura_prod.js:4
    at HTMLElement.e (aura_prod.js:4)

    ReplyDelete
    Replies
    1. Make sure the topic name is correct. Use the API name.
      Check the browser console whether you are getting any additional errors.

      Delete
    2. Hi Magulan, thanks for your quick response. I'm pretty sure that I'm using the correct name, besause push topics only has a Name field. The weird thing is that even with the error raising, I'm able to receive messages. The problem is that as I was unable to initialize the subscription object, I'm now unable to unsubscribe. Any other idea? Thanks in advance.

      Delete
    3. https://github.com/salesforce/lwc/issues/1618
      As per the above thread, it works in Non-Console Apps.

      Delete
    4. Hi Magulan. It seems related to the fact that I implemented this in a Service Console App. I was able to include the component in the Lead page layout in Sales App and it worked as expected. I can't believe that this does not work in Console Apps as I didn't found any explicit exclusion from official documentation. Thanks for your help.

      Delete