I have a Lightning Component that Subscribes to platform event. When this Component is called standalone, everything works fine. However, i need to invoke this component from Apex as well. Due to the fact that Lightning Aura Components cannot be directly invoked via APEX, i call a Visualforce Page from Apex, and this visualforce page invokes the Lightning Component. Although the Lightning Component gets displayed properly, it seems that it does not subscribe to the Platform event. Has anyone faced the same issue? Am i missing something? I believe this approach could work. Code below: Lightning Aura Component
<aura:component implements="force:hasRecordId">
<lightning:empApi aura:id="empApi" />
<aura:attribute name="channel" type="String"/> <!--default="/event/el_Change_Request_PE__e"-->
<!-- Holds the streaming event subscription -->
<aura:attribute name="subscription" type="Map" />
<aura:attribute name="cloningComplete" type="boolean" default="false" />
<aura:attribute name="recordId" type="String" access="global" />
<!-- Calls the setSpinnerToFalse controller function on component initalization -->
<aura:handler name="init" value="{!this}" action="{!c.setSpinnerToFalse}" />
<aura:if isTrue="{!v.cloningComplete}">
<section
role="dialog"
tabindex="-1"
aria-labelledby="modal-heading-01"
aria-modal="true"
aria-describedby="modal-content-id-1"
class="slds-modal slds-fade-in-open slds-modal_medium"
>
<!-- Loading spinner section -->
<!--loading spinner start... style=Brand Medium (blue dots)-->
<div aura:id="spinnerId" class="slds-spinner_container">
<div
class="slds-spinner--brand slds-spinner slds-spinner--large slds-is-relative"
role="alert"
>
<span class="slds-assistive-text">Loading</span>
<div class="slds-spinner__dot-a"></div>
<div class="slds-spinner__dot-b"></div>
</div>
</div>
<!-- Loading spinner end-->
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</aura:if>
</aura:component>
Controller JS
/** Synchronous Client-Side Controller **/
({
setSpinnerToFalse: function (component, event, helper) {
//Ebg 18-02-2021: set spinner to true
component.set("v.cloningComplete", true);
var sub = component.get("c.subscribe");
$A.enqueueAction(sub);
},
//Ebg 18-02-2021:Invokes the subscribe method on the empApi component
subscribe: function (component, event, helper) {
//Ebg 18-02-2021: Get the empApi component
const empApi = component.find("empApi");
//Ebg 18-02-2021: enable debug logging (optional)
empApi.setDebugFlag(true);
//Ebg 18-02-2021: Register error listener and pass in the error handler function
empApi.onError(
$A.getCallback((error) => {
//Ebg 18-02-2021: Error can be any type of error (subscribe, unsubscribe...)
console.error("EMP API error: ", JSON.stringify(error));
})
);
//Ebg 18-02-2021: Get the channel
const channel = component.get("v.channel");
console.log("Channel is ",component.get("v.channel"));
console.log("RecordIs is ",component.get("v.recordId"));
//Ebg 18-02-2021: Replay option to get new events
const replayId = -1;
var currentUserId = $A.get("$SObjectType.CurrentUser.Id");
console.log('line 33 userId ',currentUserId);
var receivedEvent=[];
//Ebg 18-02-2021: Subscribe to an event
empApi.subscribe(channel,replayId,
$A.getCallback((eventReceived) => {
//Ebg 18-02-2021: Process event (this is called each time we receive an event)
console.log("Received event",JSON.stringify(eventReceived)," with Opp Id ",component.get("v.recordId"));
receivedEvent=eventReceived;
//Ebg 18-02-2021: Check Opportunity Id, UserId to stop the spinner
if(/*(receivedEvent.data.payload.el_Record_Id__c==component.get("v.recordId")) &&*/(receivedEvent.data.payload.el_UserId__c==currentUserId) &&(receivedEvent.channel==channel)) {
//Ebg 18-02-2021: set spinner to false
component.set("v.cloningComplete", false);
//Ebg 18-02-2021: Navigate to opportunity record
var nav = component.get("c.navigateToRecord");
$A.enqueueAction(nav);
//Ebg 18-02-2021: Unsubscribe Event
var unSub = component.get("c.unsubscribe");
$A.enqueueAction(unSub);
}
})
)
.then((subscription) => {
//Ebg 18-02-2021: Subscription response received.
//Ebg 18-02-2021: We haven't received an event yet.
console.log("Subscription request sent to: ", subscription.channel);
//Ebg 18-02-2021: Save subscription to unsubscribe later
component.set("v.subscription", subscription);
});
},
//Ebg 18-02-2021:Invokes the unsubscribe method on the empApi component
unsubscribe : function(component, event, helper) {
// Get the empApi component
const empApi = component.find('empApi');
// Get the subscription that we saved when subscribing
const subscription = component.get('v.subscription');
// Unsubscribe from event
empApi.unsubscribe(subscription, $A.getCallback(unsubscribed => {
// Confirm that we have unsubscribed from the event channel
console.log('Unsubscribed from channel '+ unsubscribed.subscription);
component.set('v.subscription', null);
}));
},
//Ebg 18-02-2021: Function to navigate the user to the opportunity record after subscribe
navigateToRecord:function(component){
var sObectEvent = $A.get("e.force:navigateToSObject");
sObectEvent .setParams({
"recordId": component.get('v.recordId'),
"slideDevName": "detail"
});
sObectEvent.fire();
}
});
VF Page that invokes Lightning Component
<!--Ebg 26-02-2021: VF Page that will call el_Spinner component. This VF page is called by el_CustomNBAChangeAction in order to display
a spinner until cloning is complete-->
<apex:page >
<apex:includeLightning />
<div id="spinner" />
<!--Ebg 26-02-2021: Call spinner LC and pass recordId and channel as parameters-->
<script>
var channel ="{!$CurrentPage.parameters.channel}";
var recordId="{!$CurrentPage.parameters.recordId}";
console.log('VF recordId '+recordId +' channel '+channel);
$Lightning.use("c:el_SpinnerApp", function() {
$Lightning.createComponent(
"c:el_Spinner",
{channel:channel, recordId:recordId},
"spinner",
function(cmp) {
console.log("Component is created!");
console.log(cmp);
});
});
</script>
</apex:page>