[SalesForce] Application event scope in Lightning Console Apps across console tabs

Does anyone know if there is documented or undocumented behavior of if same components which live in different Lightning Console tabs will still listen to an application event fired from, say, the utility bar?

I'm trying to verify some behavior from a colleague and wanted to see what other findings were before I create a POC myself to verify.

Is this expected behavior that multiple console tabs are considered one "application" ?

Best Answer

My POC shows that this is indeed true, probably by design (I guess it makes sense, sort of).

Lightning-console apps consider every LOADED tab in scope of an application event. To further complicate this behavior, if more than one record tab is LOADED, then you refresh the browser, only the current record tab is back in scope of an application event. I think this is because the second tab hasn't bootstrapped into the one.app namespace yet.

FYI, I'm using my own service component framework (https://github.com/tsalb/sfdc-lightning-service-components) to fire these events, but the underlying application event firing mechanism is the same, I just have method wrappers to help fire generic ones.


Place both on same Lightning Record Page in Lightning-console app


AppEventFire.cmp

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
  <c:EventService aura:id="eventService"/>
  <lightning:button label="Fire App Event" onclick="{! c.handleFireAppEventClick }"/>
</aura:component>

AppEventFireController.js

({
  handleFireAppEventClick : function(component, event, helper) {
    var eventService = component.find("eventService");
    eventService.fireAppEvent("TEST_RECORD_EVENT_FIRE");
  }
})

AppEventListener.cmp

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">

    <aura:handler event="c:ServiceAppEvent" action="{! c.handleApplicationEvent }"/>

    <aura:attribute name="record" type="Object"/>
    <aura:attribute name="simpleRecord" type="Object"/>
    <aura:attribute name="recordError" type="String"/>

    <force:recordData aura:id="recordHandler"
      recordId="{!v.recordId}"
      layoutType="FULL"
      targetRecord="{!v.record}"
      targetFields="{!v.simpleRecord}"
      targetError="{!v.recordError}"
      mode="EDIT"
      />

    {! v.simpleRecord.AppEventCount__c }

</aura:component>

AppEventListenerController.js

({
  handleApplicationEvent : function(component, event, helper) {
    var params = event.getParams();

    switch(params.appEventKey) {
      case "TEST_RECORD_EVENT_FIRE":
        var currentCount = component.get("v.simpleRecord.AppEventCount__c");
        currentCount++;
        component.set("v.simpleRecord.AppEventCount__c", currentCount);

        component.find("recordHandler").saveRecord($A.getCallback(function(saveResult) {
          if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
            component.find("recordHandler").reloadRecord();
          }
        }));
        break;
    } 
  },
})

Then open up two records within the same Lightning-console app, fully load both (so that the fire.cmp and listener.cmp exist, are rendered). You'll see that if you fully load two Lightning-console app tabs, then click the button from either one, both will receive it. I'm writing to server to verify that these application events persist and it's not just a trick of browser / component memory.

P.S. I've added what I'm calling a Record Event to my framework which deals with this very specific issue, very specifically inside lightning-console apps. I'll update my framework repo when I get some time.

Related Topic