TypeORM

TypeORM - data-mapper ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases. Works in Node.JS and Browser.

Subscribers and Entity Listeners

You can listen to following events in ORM:

There are two ways to listen to events:

Subscribers

Subscribers are separate classes that implement EntitySubscriberInterface interface and marked with @EventSubscriber() decorator.

Subscribers (or directories where they are) must be included in the connection options during connection:


const connectionOptions: ConnectionOptions = {
    /* ... */
    subscribers: [__dirname + "/modules/**/subscriber/*.ts"]
}
        

Here how EntitySubscriberInterface interface looks like:


export interface EntitySubscriberInterface<Entity> {

    /**
     * Returns the class of the entity to which events will listen.
     * If this method is omitted, then subscriber will listen to events of all entities.
     */
    listenTo?(): Function;

    /**
     * Called after entity is loaded from the database.
     */
    afterLoad?(entity: Entity): Promise<any>|void;

    /**
     * Called before entity is inserted to the database.
     */
    beforeInsert?(event: InsertEvent<Entity>): Promise<any>|void;

    /**
     * Called after entity is inserted to the database.
     */
    afterInsert?(event: InsertEvent<Entity>): Promise<any>|void;

    /**
     * Called before entity is updated in the database.
     */
    beforeUpdate?(event: UpdateEvent<Entity>): Promise<any>|void;

    /**
     * Called after entity is updated in the database.
     */
    afterUpdate?(event: UpdateEvent<Entity>): Promise<any>|void;

    /**
     * Called before entity is removed from the database.
     */
    beforeRemove?(event: RemoveEvent<Entity>): Promise<any>|void;

    /**
     * Called after entity is removed from the database.
     */
    afterRemove?(event: RemoveEvent<Entity>): Promise<any>|void;

}
        

And here is how your subscriber should look like:


import {EventSubscriber, EntitySubscriberInterface} from "typeorm";

@EventSubscriber()
export class EverythingSubscriber implements EntitySubscriberInterface<any> {

}
        

Then you can add any method you want to listen to, for example let's add beforeInsert method:


import {EventSubscriber, EntitySubscriberInterface} from "typeorm";

@EventSubscriber()
export class EverythingSubscriber implements EntitySubscriberInterface<any> {

    beforeInsert(event: InsertEvent<any>) {
        console.log(`BEFORE ENTITY INSERTED: `, event.entity);
    }

}
        

This way you can implement any method, to listen to any event:


import {EventSubscriber, EntitySubscriberInterface} from "typeorm";

@EventSubscriber()
export class EverythingSubscriber implements EntitySubscriberInterface<any> {

    beforeInsert(event: InsertEvent<any>) {
        console.log(`BEFORE ENTITY INSERTED: `, event.entity);
    }

    beforeUpdate(event: UpdateEvent<any>) {
        console.log(`BEFORE ENTITY UPDATED: `, event.entity);
    }

    beforeRemove(event: RemoveEvent<any>) {
        console.log(`BEFORE ENTITY WITH ID ${event.entityId} REMOVED: `, event.entity);
    }

    afterInsert(event: InsertEvent<any>) {
        console.log(`AFTER ENTITY INSERTED: `, event.entity);
    }

    afterUpdate(event: UpdateEvent<any>) {
        console.log(`AFTER ENTITY UPDATED: `, event.entity);
    }

    afterRemove(event: RemoveEvent<any>) {
        console.log(`AFTER ENTITY WITH ID ${event.entityId} REMOVED: `, event.entity);
    }

    afterLoad(entity: any) {
        console.log(`AFTER ENTITY LOADED: `, entity);
    }

}
        

There is also a special listenTo method that can be implemented to indicate which entity this subscriber must listen to. For example, let's say we have Post entity and want to listen to only its events:


import {EventSubscriber, EntitySubscriberInterface} from "typeorm";

@EventSubscriber()
export class EverythingSubscriber implements EntitySubscriberInterface<Post> {

    listenTo() {
        return Post;
    }

    beforeInsert(event: InsertEvent<Post>) {
        console.log(`BEFORE Post INSERTED: `, event.entity);
    }

    beforeUpdate(event: UpdateEvent<Post>) {
        console.log(`BEFORE Post UPDATED: `, event.entity);
    }

    beforeRemove(event: RemoveEvent<Post>) {
        console.log(`BEFORE Post WITH ID ${event.entityId} REMOVED: `, event.entity);
    }

    afterInsert(event: InsertEvent<Post>) {
        console.log(`AFTER Post INSERTED: `, event.entity);
    }

    afterUpdate(event: UpdateEvent<Post>) {
        console.log(`AFTER Post UPDATED: `, event.entity);
    }

    afterRemove(event: RemoveEvent<Post>) {
        console.log(`AFTER Post WITH ID ${event.entityId} REMOVED: `, event.entity);
    }

    afterLoad(entity: Post) {
        console.log(`AFTER Post LOADED: `, entity);
    }

}
        

If you are using service container, then you can inject services into your subscribers. Learn more about how to use service container [here].

Entity Listeners

Entity listeners can be used right in your entities. Its working if you put decorator on specific entity method, and this method will be executed when appropriate event occur. Here is list of decorators you can use:

For example, let's say you have Post entity and you want to listen to its events:


import {Entity, PrimaryGeneratedColumn, Column, AfterLoad, BeforeInsert, AfterInsert, BeforeUpdate, AfterUpdate, BeforeRemove, AfterRemove} from "typeorm";

@Entity()
export class Post {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column()
    text: string;

    uid: number;

    @AfterLoad()
    generateRandomNumbers() {
        console.log(`event: Post "${this.title}" entity has been loaded and callback executed`);
        this.uid = Math.ceil(Math.random() * 1000);
    }

    @BeforeInsert()
    doSomethingBeforeInsertion() {
        console.log("event: Post entity will be inserted so soon...");
    }

    @AfterInsert()
    doSomethingAfterInsertion() {
        console.log("event: Post entity has been inserted and callback executed");
    }

    @BeforeUpdate()
    doSomethingBeforeUpdate() {
        console.log("event: Post entity will be updated so soon...");
    }

    @AfterUpdate()
    doSomethingAfterUpdate() {
        console.log("event: Post entity has been updated and callback executed");
    }

    @BeforeRemove()
    doSomethingBeforeRemove() {
        console.log("event: Post entity will be removed so soon...");
    }

    @AfterRemove()
    doSomethingAfterRemove() {
        console.log("event: Post entity has been removed and callback executed");
    }

}
        
Fork me on GitHub