Nest Js dynamic cron jobs

Mukhiddin Jumaniyazov
2 min readOct 2, 2023

--

Nest Js has a great component which implement cron jobs. the greatest feature we can make jobs dynamic, it is very helpful in our project

I want to share knowledge that how implement this feature in our project

let’s assume we have many task and every task should run different a specific time, our task is collection all jobs and register to nest js schedule component

for install component run it in terminal

$ npm install --save @nestjs/schedule

First of all, we need to create Abstract class which all cron service get inherent from it

export abstract class AbstractScheduler {

public abstract name: string;

public abstract timeExpression: string;

public abstract run();
}

there are two property and method, name is name of the cron job. timeExpression is which time period cron should be call run function

let’s create first cron job

@Injectable()
export class DailyReportScheduler extends AbstractScheduler {
public name: string = 'daily_report';

public timeExpression: string = CronExpression.EVERY_DAY_AT_8PM;

public run() {
// calculate and send daily report
}
}

and second cron job

@Injectable()
export class MonthlyReportScheduler extends AbstractScheduler {

public name: string = 'monthly_report';

public timeExpression: string = CronExpression.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT;

public run() {
// calculate and send monthly report
}
}

add following code to your module for collecting cron jobs to one service provider

@Module({

providers: [
MonthlyReportScheduler,DailyReportScheduler
{
provide: 'SCHEDULES',
useFactory: (...schedules) => {
return schedules;
},
inject: [
MonthlyReportScheduler, DailyReportScheduler
],
},
],
exports: [],
})
export class AppModule {
}

also register Scheduler classes as provider. We create provider with tag SCHEDULES which we can inject this provider with alias inside of constructor

@Injectable()
export class TaskScheduleRegistery implements OnApplicationBootstrap {
private readonly logger = new Logger(TaskScheduleService.name);

onApplicationBootstrap(): any {
this.logger.log('Task scheduler has been booting');
this.registerCronJobs();
}

constructor(
@Inject('SCHEDULES')
private readonly schedules: AbstractScheduler[],
private readonly scheduleRegistry: SchedulerRegistry,
) {
}

registerCronJobs() {
for (const job of this.schedules) {
this.logger.log(`${job.name} cron has added with expression ${job.timeExpression}`);

this.scheduleRegistry.addCronJob(job.name, new CronJob(job.timeExpression, () => {
this.logger.log(`${job.name} cron is starting with expression ${job.timeExpression}`);

job.run();

}, () => {
this.logger.log(`${job.name} cron has completed with expression ${job.timeExpression}`);
}, true));
}
}
}

this service has implemented OnApplicationBootstrap interface, while nest js application bootstrapping then our jobs being register to the nestjs schedule component

if you want to know more go to nest js documentation

--

--

Mukhiddin Jumaniyazov

Senior Full Stack Software engineer (Php/Symfony/NestJs/ReactJs