Looping of Asynchronous/Apex calls from LWC components

 Many a times we see use cases where based on an event we would need to make multiple apex calls.

While it is easy to handle fixed no of calls to different methods with Promise.all() there is no specific solution use case where we need to make random number of calls based on a condition to the same apex method. Below we see one such simple sample use case

The below example keeps on doing async class until it meets one if the exit conditions either 50 contacts are fetched or a contact with Josh Davis Name is fetched.

as this is loop of async calls on the ui we can clearly see contacts showing up one by one with a gap of 2 seconds.

<template>
    <lightning-card title="ApexImperativeMethod" icon-name="custom:custom63">
        <div class="slds-m-around_medium">
            <p class="slds-m-bottom_small">
                <lightning-button label="Load Contacts"
                        onclick={handleLoad}></lightning-button>
            </p>
            <template if:true={contacts}>
                <template for:each={contacts} for:item="contact">
                    <p key={contact.Id}>{contact.Name}</p>
                </template>
            </template>
           
        </div>
    </lightning-card>
</template>


import { LightningElement } from 'lwc';
import getContactList from '@salesforce/apex/AsyncAwaitDemonstrationController.getContactList';

export default class AsyncAwaitDemonstration extends LightningElement {
    contacts = [];
    error;
   
    handleLoad() {
        this.getContactsInLoop();
    }

    async getContactsInLoop(){

        try{

            while(this.contacts.length < 50){

                let params = {offset : this.contacts ? this.contacts.length : 0 };

                // server side call example
                let currentContacts = await getContactList(params);

                this.contacts = [...this.contacts, ...currentContacts];

                if(currentContacts[0].Name === 'Josh Davis')
                return;
                
                // native call example
                await this.sleep(2000);

            }

        } catch (error) {
            console.error(error);
        }
       
    }

    sleep(ms) {
        // eslint-disable-next-line @lwc/lwc/no-async-operation
        return new Promise(resolve => setTimeout(resolve, ms));
    }

}


public with sharing class AsyncAwaitDemonstrationController {
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContactList(Integer offset) {
        return [
            SELECT Id, Name, Title, Phone, Email
            FROM Contact
            WITH SECURITY_ENFORCED
            LIMIT 1
            OFFSET :offset
        ];
    }
}

Comments

Popular Posts