Calling Apex method at regular interval from Lightning Component

Importance of $A.getCallback and Modifying Components Outside the Framework Lifecycle

Calling Apex method at regular interval in lightning component

Recently, I was in need of Lightning Component, which can poll Apex class at regular interval and display status of some process running in background. Initially, I thought its very easy and straight forward. Just like we do in Visualforce, use window.setInterval method of Javascript and I came up with below code.

RefreshContactCounter.cls

/**
 * @Author		:		Jitendra Zaa
 * @Date		:		Nov-09-2016
 * @Desc		:		This class is used by LEX component - PollApexClass
 * 			:		It returns total number of contacts in system
 * */

public class RefreshContactCounter {
    
    @AuraEnabled
    public static Integer getContactCount(){
         AggregateResult[] groupedResults = [SELECT count(Id) totalCount FROM Contact];
		Object totalCount = groupedResults[0].get('totalCount');
        return (Integer) totalCount ;
    }

}

PollApexClass.cmp

 
 <aura:component controller="RefreshContactCounter">    
    <aura:attribute type="Decimal" name="contactCount" />
     <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> 
<div class="slds"> 
<article class="slds-card slds-card--narrow">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media--center slds-has-flexi-truncate">
<div class="slds-media__figure">
                        <c:svg xlinkHref="/resource/SLDS_2_0_3/assets/icons/standard-sprite/svg/symbols.svg#contact" class="slds-icon slds-icon-standard-contact slds-icon--small" /> 
                    </div>
<div class="slds-media__body slds-truncate">

<h2>
                            <span class="slds-text-heading--small"> Total Contacts in system</span>
                        </h2>
                    </div>
                </header> 
            </div>
<div class="slds-card__body slds-align--absolute-center slds-text-heading--large"> {!v.contactCount }</div>
<div class="slds-card__footer"> Refresh rate - every 5 seconds </div>
        </article>        
    </div>    
</aura:component>

PollApexClassController.js

({
	doInit : function(component, event, helper) {
		helper.pollApex(component, event, helper);
	}
})

PollApexClassHelper.js

({
    pollApex : function(component, event, helper) { 
        helper.callApexMethod(component,helper);
        
        //execute callApexMethod() again after 5 sec each
        window.setInterval(helper.callApexMethod(component,helper), 
		5000,);      
    },
    handleResponse : function (response, component){
        var retVal = response.getReturnValue() ;
        component.set("v.contactCount",retVal); 
    },
    callApexMethod : function (component,helper){    
        var action = component.get("c.getContactCount");        
        action.setCallback(this, function(response) {
            this.handleResponse(response, component);
        });
        $A.enqueueAction(action); 
    } 
})

In above helper javascript file, we are using window.setInterval() method of Javascript, to call Apex class at interval of 5sec.

DemoApp.app

<aura:application >
    <ltng:require styles="/resource/SLDS_2_0_3/assets/styles/salesforce-lightning-design-system.css" />
 	<c:PollApexClass /> 
</aura:application>

If we try to run above application, it doesn’t work as expected and returns below error

Windows setInterval error in Lightning Component
Windows.setInterval() error in Lightning Component

After going through documentation, I came across this page, which hints how we can modify Lightning component’s content outside its lifecycle.

In PollApexClassHelper.js file, we just need to change method pollApex by below code :

pollApex : function(component, event, helper) { 
        helper.callApexMethod(component,helper);
        
        //execute callApexMethod() again after 5 sec each
        window.setInterval(
            $A.getCallback(function() { 
                helper.callApexMethod(component,helper);
            }), 5000
        );      
    }

Demo :

poll apex class in lex compressor

Related posts

9 thoughts on “Calling Apex method at regular interval from Lightning Component”

  1. Superb finding! One of my Appexchange component uses similar real-time update approach. Will this approach show updated data without tap or click on component/window? Thanks for the share!

  2. Hi , Thanks for sharing this.Was very helpful.
    Also, I need to make a small change in this.
    Let say it the count record value = 40 , then this should stop calling or it should stop. I tried with :
    if(record count != 40)
    //run the code window.setInterval(
    else if(record count == 40)
    // do something else

    when I debug this , when the record count comes to 40 , still this is calling the apex action at 5 sec of interval.

    Can you please suggest some method to stop this time interval calling at some condtion.

    Thanks and regards
    Apoorv Jain

    1. Hi Apoorva,

      Yes we can kill polling by using such condition. I tried below logic and it works well.

      pollApex : function(component, event, helper) {
      helper.callApexMethod(component,helper);

      //execute after 5 sec each till next case is not assigned
      var pollId = window.setInterval(
      $A.getCallback(function() {
      helper.callApexMethod(component, helper, pollId);
      }), 5000
      );

      },

      callApexMethod : function (component,helper,pollId){
      var action = component.get(“c.getContactCount”);
      action.setCallback(this, function(response) {
      this.handleResponse(response, component, pollId);
      });
      $A.enqueueAction(action);
      },

      handleResponse : function (response, component, pollId){
      var retVal = response.getReturnValue() ;
      component.set(“v.contactCount”,retVal);
      //logic to kill polling
      if(retVal > 40){
      //This will kill your batch job
      window.clearInterval(pollId);
      }
      }

      Please let me know if it solves your purpose. Cheers.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.