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.
-
2When 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.– nbrownApr 19, 2021 at 12:33
-
hi @nbrown. can u please guide me how to track the status of Queable job in apex class.– user96288Apr 20, 2021 at 6:04
1 Answer
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));
}
}