Carven
Carven

Reputation: 15648

NestJs: How to access database in entity listeners?

I've got a @BeforeInsert() listener in my Post entity. The listener is supposed to create a unique slug for the slug column before insertion.

For example:

export class Post extends BaseEntity {
    @PrimaryGeneratedColumn()
    id: number

    @Column()
    title: string

    @Column()
    slug: string

    @BeforeInsert()
    private updateSlug() {
        this.slug = slugify(this.title)
        // I will need to access the database to check whether the same slug has existsed already or not. 
        // How do I access the database in this listener method?
    }
}

Since the slug column is supposed to be unique, I will have to check in the database to know whether the same slug already exists. If the slug already exists, I will then need to append a number behind the slug, like hello-word-1.

However, to do so, I will need to access the Post repository of the entity in the Post entity class before I can access the database. But I don't see how I can inject the repository into my Post entity class to access the database for this purpose.

How should I approach this problem?

Upvotes: 2

Views: 6467

Answers (1)

Kim Kern
Kim Kern

Reputation: 60357

As far as I know it's not possible to use dependency injection in typeorm entities, since they are not instantiated by nest. You can however use an EntitySubscriber instead which can inject dependencies. See the solution from this Github issue:

import { Injectable } from '@nestjs/common';
import { InjectConnection, InjectRepository } from '@nestjs/typeorm';
import { Connection, EntitySubscriberInterface, InsertEvent, Repository } from 'typeorm';
import { Post } from '../models';

@Injectable()
export class PostSubscriber implements EntitySubscriberInterface {

  constructor(
    @InjectConnection() readonly connection: Connection,
    // Inject your repository here
    @InjectRepository(Photo) private readonly postRepository: Repository<Post>,
  ) {
    connection.subscribers.push(this);
  }

  listenTo() {
    return Post;
  }

  beforeInsert(event: InsertEvent<Post>) {
    // called before insert
  };

}

Upvotes: 4

Related Questions