1

My LWC calls a batch job class which inserts contacts. This works fine, however I am now trying to display a progress bar or spinner to show the status of the batch job.

I am trying to pass the Job Id into an Apex method which queries and returns the status.

As I want this fluid, it needs to 'refresh' and call frequently until the job is done in order to show the progress bar.

My Method is failing to execute. -> getBatchJobStatus

I also occasionally get a [Violation] 'setInterval' handler took xx ms.

Below is my .js

import initiateContactBatch from '@salesforce/apex/BatchCreateContactController.initiateContactBatch';
import getBatchJobStatus from '@salesforce/apex/BatchCreateContactController.getBatchJobStatus';
export default class BombBurstContacts extends LightningElement {

    

    @track numberInput = 0;
    @track jobID = null;
    @track createError;
    @track error;
    @track record;
    @track processing = false;
    @track jobPercentage;
    @track totalJobItems;
    @track jobItemsProcessed;
    @track status;
    @track progress = 500;  
  
    onChange(event){
        this.numberInput = event.target.value;
        console.log('this.numberInput' + this.numberInput);
    }
    
    createRecords(){
        
        initiateContactBatch({ numberOfRecords : this.numberInput })
            .then(result => {
                this.jobID = result;
                this.processing = true;
                console.log('this.jobID' + this.jobID);
                console.log('this.processing' + this.processing);

                this.connectedCallback();
                
            })
            .catch(error => {
                this.createError = error;
                console.log('this.createError' + this.createError);
                
            });
    }

    connectedCallback() {  
        if(this.jobID != null){
            this._interval = setInterval(() => {  
                
                
               //this.getStatus();

               getBatchJobStatus({ jobID : this.jobID})
                .then(result => {
                    this.record = result;
                    console.log('this.record' + this.record);
                })
                .catch(error => {
                    this.error = error;
                    console.log('this.error' + this.error);
                });
                
                this.progress = this.progress + 25000;
                console.log('this.progress' + this.progress);
                
                if ( this.progress === 200000 ) {  
                    clearInterval(this._interval);  
                }  
            }, this.progress);  
        }
  
    }  

    // getStatus(){
    //     getBatchJobStatus({ jobID : jobID})
    //     .then(result => {
    //         this.record = result;
    //         console.log('this.record' + this.record);
    //     })
    //     .catch(error => {
    //         this.error = error;
    //         console.log('this.error' + this.error);
    //     });
    // }


    
    
}
6
  • [Violation] 'setInterval' handler took xx ms usually means that the function took more time to execute than expected (causing UI performance issues). Are you trying to show only the batch job status only? I'm doubt if placing this code inside connectedCallback is the right approach since a hard (browser) refresh would give you a null jobId.
    – arut
    Aug 27, 2020 at 12:37
  • Hi there! The connectedCallback isn’t initiated until the createRecords happened so there will always be a JobID won’t there? I do apologise my inexperience if I am wrong! - Ideally I want the full batchJob record so I can find the difference between totalJobItems and Completed to work out the percentage for the loading bar. Aug 27, 2020 at 12:39
  • 1
    The connectedCallback isn’t initiated until the createRecords happened so there will always be a JobID won’t there ... You are right about the jobID here but connectedCallback is a life cycle hook that will execute anytime an insertion occurs in DOM. So, lets say the createRecords called the connectedCallback and then some user action caused an update in the DOM, connectedCallback would get called again. So, another setInterval callback will be queued up leading to redundancy. While I would still look for another approach, I doubt if this code is the right way.
    – arut
    Aug 27, 2020 at 12:53
  • My suggestion would be to create a separate progress bar component (with a refresh icon button) and use it your code. Refer to the sample shown in the documentation section here: developer.salesforce.com/docs/component-library/bundle/…. This child component could dispatch a custom event on click of the refresh button (or automatically after certain interval) to the parent component (asking to fetch the latest job status) and the parent component could send the information to a public method in the child component.
    – arut
    Aug 27, 2020 at 13:44
  • This way you would be breaking down your code into simple re-usable components. If you are running into issues doing this, let me know. Also, there could be other ways to do this.
    – arut
    Aug 27, 2020 at 13:44

1 Answer 1

0

@arut was correct.

The connectedCallback isn’t initiated until the createRecords happened so there will always be a JobID won’t there ... You are right about the jobID here but connectedCallback is a life cycle hook that will execute anytime an insertion occurs in DOM. So, lets say the createRecords called the connectedCallback and then some user action caused an update in the DOM, connectedCallback would get called again. So, another setInterval callback will be queued up leading to redundancy. While I would still look for another approach, I doubt if this code is the right way.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .