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