I have a subscriber for NestJS to listen to any create, update or delete events (TypeORM). When one of these events is fired, I'd like to use an injected service in order to create a new revision entry.
However, it seems I cannot get the dependency loaded inside of the subscriber and the service comes back as being undefined
Key files:
app.module.ts
@Module({
imports: [
HttpModule,
TypeOrmModule.forRoot({
type: (process.env.DB_TYPE as any) || 'postgres',
host: process.env.DB_HOST || '127.0.0.1',
port: (process.env.DB_PORT as any) || 5432,
username: process.env.DB_USER || 'root',
password: process.env.DB_PASS || '',
database: process.env.DB_NAME || 'test',
entities: [join(__dirname, '**/**.entity{.ts,.js}')],
synchronize: true,
logging: 'all',
logger: 'advanced-console',
subscribers: [EntityModificationSubscriber],
}),
TypeOrmModule.forFeature([
RevisionEntity,
]),
TerminusModule.forRootAsync({
// Inject the TypeOrmHealthIndicator provided by nestjs/terminus
inject: [TypeOrmHealthIndicator, MicroserviceHealthIndicator],
useFactory: (db, msg) => getTerminusOptions(db, msg),
}),
GraphQLModule.forRoot({
debug: true,
playground: true,
typePaths: ['./**/*.graphql'],
}),
],
controllers: [AppController],
providers: [
RevisionService,
EntityModificationSubscriber,
],
})
entity_modification_subscriber.ts
import {EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent, UpdateEvent} from 'typeorm';
import {RevisionEntity, RevisonEntityStatus} from '../entities/revison.entity';
import {RevisionService} from '../services/revisions.service';
import {Injectable} from '@nestjs/common';
@Injectable()
@EventSubscriber()
export class EntityModificationSubscriber implements EntitySubscriberInterface {
constructor(private revisionService: RevisionService) {
}
// tslint:disable-next-line:no-empty
afterInsert(event: InsertEvent<any>): Promise<any> | void {
const revision = new RevisionEntity();
revision.action = RevisonEntityStatus.Created;
}
afterUpdate(event: UpdateEvent<any>): Promise<any> | void {
}
// tslint:disable-next-line:no-empty
afterRemove(event: RemoveEvent<any>) {
// this.revisionService.createRevisionEntry(revision);
}
}
The only way I found to inject a dependency into a subscriber using NestJS, was not to register that subscriber in the TypeORM configuration. I subscribe it manually into the TypeORM connection on subscriber's constructor.
import { EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent, UpdateEvent, Connection } from 'typeorm';
import { RevisionEntity, RevisonEntityStatus } from '../entities/revison.entity';
import { RevisionService } from '../services/revisions.service';
import { Injectable } from '@nestjs/common';
@Injectable()
@EventSubscriber()
export class EntityModificationSubscriber implements EntitySubscriberInterface {
constructor(private readonly connection: Connection, private readonly revisionService: RevisionService) {
connection.subscribers.push(this); // <---- THIS
}
// tslint:disable-next-line:no-empty
afterInsert(event: InsertEvent<any>): Promise<any> | void {
const revision = new RevisionEntity();
revision.action = RevisonEntityStatus.Created;
//this.revisionService <- should be working!
}
afterUpdate(event: UpdateEvent<any>): Promise<any> | void {
}
// tslint:disable-next-line:no-empty
afterRemove(event: RemoveEvent<any>) {
// this.revisionService.createRevisionEntry(revision);
}
}
Then in your app.module on the TypeORM module configuration (TypeOrmModule.forRoot). Remove the line:
subscribers: [EntityModificationSubscriber],
It solved to me, hope it help others. You can find discussions about that in some NestJS issues/pull requests.
https://github.com/nestjs/typeorm/issues/85
https://github.com/nestjs/typeorm/pull/27
Hi the problem is that If you want to preform database actions you would have to use:
event.manager
and Don't use getEntityManager() or getRepository() or any other global function. This is due to a transaction. Save is running in a transaction and your data is saved in a transaction which is not committed yet. But global functions you use are running out of transaction.
more about issue here:
https://github.com/typeorm/typeorm/issues/681
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With