0

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>
0

I solved the issue by removing the Lightning Component invocation. Instead, what i did was to subscribe/unsubscribe to platform event from the visualforce and perform the navigation to the record through sforce.one object event. more information can be found here: https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/salesforce1_dev_jsapi_sforce_one.htm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.