0

I try to realize a little NestJS application in which I want to integrate a task scheduler. One of the first tasks of this scheduler will be to update data in database. This task service will user a UserService like below :

import {
  Injectable,
  Inject,
  UnprocessableEntityException,
  HttpStatus,
} from '@nestjs/common';
import { Repository } from 'typeorm';
import * as bcrypt from 'bcryptjs';
import { User, UserStatus } from './user.entity';
import { LoggerService } from '../../../logger/logger.service';
import { HammerErrors } from 'src/error/hammer.errors';
import * as Config from '../../../config/global.env';

@Injectable()
export class UserService {
  private readonly _logger = new LoggerService(UserService.name);

  constructor(
    @Inject('USER_REPOSITORY')
    private _userRepository: Repository<User>,
  ) {}
  ....
  async reactiveBlockedUsers() {
    this._logger.setMethod(this.reactiveBlockedUsers.name);
    this._logger.log(`Update blocked users`);
    await this._userRepository
      .createQueryBuilder('hm_users')
      .update(User)
      .set({
        nextValidDate: null,
      })
      .where(
        `hm_users.nextValidDate IS NOT NULL hm_users.nextValidDate < utc_timestamp()`,
      )
      .execute();
    return null;
  }

}

My task service is as follows:

import { LoggerService } from '../../../logger/logger.service';
import { UserService } from '../../providers/user/user.service';
import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private _logger = new LoggerService(TasksService.name);

  constructor(private _userService: UserService) {}

  @Cron(CronExpression.EVERY_MINUTE)
  async reactiveUsers() {
    this._logger.setMethod(this.reactiveUsers.name);
    this._logger.log(`Reactive blocked users`);
    try {
      await this._userService.reactiveBlockedUsers();
    } catch (error) {
      this._logger.log(error);
    }
  }

  @Cron(CronExpression.EVERY_MINUTE)
  startBatchJobs() {
    this._logger.setMethod(this.startBatchJobs.name);
    this._logger.log(`Start batch job service`);
  }

  triggerNotifications() {}
}

The task module is the following :

import { Module } from '@nestjs/common';
import { TasksService } from './tasks.service';
import { UserService } from 'src/shared/providers/user/user.service';
import { Repository } from 'typeorm';

@Module({
  providers: [
    TasksService,
    UserService,
    {
      provide: 'USER_REPOSITORY',
      useClass: Repository,
    },
  ],
})
export class TasksModule {}

When I the process works, I have the following trap : [INFO] 06/05/2020 19:57:00.024 [TasksService.reactiveUsers] TypeError: Cannot read property 'createQueryBuilder' of undefined

Or : (node:13668) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'createQueryBuilder' of undefined at Repository.createQueryBuilder (D:\dev\hammer\hammer-server\node_modules\typeorm\repository\Repository.js:17:29) at UserService.reactiveBlockedUsers (D:\dev\hammer\hammer-server\dist\src\shared\providers\user\user.service.js:183:14) at TasksService.reactiveUsers (D:\dev\hammer\hammer-server\dist\src\shared\services\tasks\tasks.service.js:25:33) at CronJob.fireOnTick (D:\dev\hammer\hammer-server\node_modules\cron\lib\cron.js:562:23) at Timeout.callbackWrapper [as _onTimeout] (D:\dev\hammer\hammer-server\node_modules\cron\lib\cron.js:629:10) at listOnTimeout (internal/timers.js:549:17) at processTimers (internal/timers.js:492:7) (node:13668) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2) (node:13668) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

when I suppress the try catch.

For me it is a problem of providing Repositiry module which is injected in UserService but I don't understand how that works and how to solve this problem.

If somebody has an idea, I will be interested.

Thanks for your help.

afontange
  • 41
  • 2
  • 4
  • Your title sounds like an exact duplicate of this question: https://stackoverflow.com/questions/130794/what-is-dependency-injection , but your question itself seems to be about a specific error in your specific code. Your question would be more likely to get an answer if the title was more specific to your problem :) – MyStackRunnethOver May 06 '20 at 20:12

2 Answers2

1

Repository is an abstract class in TypeORM and cannot be instantiated directly. Nest does what it can around this, but ultimately it will provide an undefined and thus, calling createQueryBuilder will give you a problem. As you are using TypeORM, is there a reason you aren't using the @nestjs/typeorm package? It manages creating the repository classes for you and makes things much easier. You are are gungho about not using the package, you can always create your own Repository class UserRepository extends Repository decorated with the proper metadata and all, and then use that class instead of Repository

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
0

Thank you for information I did not know about this existing package. I will try to implement your proposal. I am a novice in these technology and I discover day by day something new. From beginning of March I have learned HTML, CSS, Javascript, Typescript NestJs and Angular and now I try to implement a little project with all these technologies. I think that I have many hole in my knowledge and I apreciate your answer to give me those informations.

afontange
  • 41
  • 2
  • 4