0

we have a lightning button on community. when we click on it a queable class gets triggered and it will update forms status. whenever I am clicking on the button it is taking some time to update the forms. so I tried to add a spinner after the button click.. but the spinner is running only at the time of browser load.. but I want it to be load till the queable job gets completed please help me on this..... Thanks in advance.

2
  • 2
    When your queueable gets enqueued it will generate an Apex Job Id. You can have your component periodically check the status of the Apex job to see its status.
    – nbrown
    Apr 19, 2021 at 12:33
  • hi @nbrown. can u please guide me how to track the status of Queable job in apex class.
    – user96288
    Apr 20, 2021 at 6:04

1 Answer 1

3

When you enqueue a queueable, the system will generate an Apex job ID. You can use this job ID to check on the status of your queueable periodically so that your component is reacting to its status. ("Monitor Asynchronous Apex" on Trailhead is a good starting point)

// ... inside some aura method that enqueues a queueable

Id asyncApexJobId = System.enqueueJob(new MyQueueableClass());
return asyncApexJobId;

You didn't specify whether you're using Aura or LWCs, but the implementation would be similar to below.

You need an Apex class to fetch your jobs.

public with sharing class AsyncApexJobService {

    @AuraEnabled
    public static List<AsyncApexJob> getJobsById(List<Id> jobIds) {
        Set<Id> setOfJobIds = new Set<Id>(jobIds);
        return [
             SELECT Id
                ,ApexClassID
                ,CompletedDate
                ,ExtendedStatus
                ,JobItemsProcessed
                ,JobType
                ,MethodName
                ,NumberOfErrors 
                ,Status
                ,TotalJobItems
            FROM AsyncApexJob
            WHERE Id IN :jobIds
        ];
    }

}

Adapt this code as you need:

import { LightningElement, api } from 'lwc';
import getJobsById from '@salesforce/apex/AsyncApexJobService.getJobsById';

export default class MyComponent extends LightningElement {

    jobIds = [];

    deferCheckJobs() {
        // this checks for jobs on a 3 second timer. Adjust your timer accordingly and provide a UX that lets the 
        // end-user know about how long they should be expecting to wait.
        setTimeout(() =>
            this.checkJobs()
        , 3000);
    }
    
    checkJobs() {
        getJobsById({ jobIds: this.jobIds })
            .then(asyncApexJobs => {
                /* Handle different job statuses here */

                // check for jobs that have not ended. These will be jobs that are not Aborted, Completed, or Failed
                let inProcessJobs = asyncApexJobs.find((j) => {
                    let status = j.Status;
                    let inProgress = (status != 'Aborted' && status != 'Completed' && status != 'Failed');
                    
                    return inProgress;
                });

                // if there were jobs that didn't complete, check again
                if(inProcessJobs) {
                    this.deferCheckJobs();
                } else { 
                    // otherwise all the jobs are done
                    /* Handle all jobs ended */
                }
            })
            .catch(err => console.error(err));
    }

}

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