# Listeners and Subscribers

## What is an Entity Listener?[​](#what-is-an-entity-listener "Direct link to What is an Entity Listener?")

Any of your entities can have methods with custom logic that listen to specific entity events. You must mark those methods with special decorators depending on what event you want to listen to.

**Note:** Do not make any database calls within a listener, opt for [subscribers](#what-is-a-subscriber) instead.

### `@AfterLoad`[​](#afterload "Direct link to afterload")

You can define a method with any name in entity and mark it with `@AfterLoad` and TypeORM will call it each time the entity is loaded using `QueryBuilder` or repository/manager find methods. Example:

```
@Entity()

export class Post {

    @AfterLoad()

    updateCounters() {

        if (this.likesCount === undefined) this.likesCount = 0

    }

}
```

### `@BeforeInsert`[​](#beforeinsert "Direct link to beforeinsert")

You can define a method with any name in entity and mark it with `@BeforeInsert` and TypeORM will call it before the entity is inserted using repository/manager `save`. Example:

```
@Entity()

export class Post {

    @BeforeInsert()

    updateDates() {

        this.createdDate = new Date()

    }

}
```

### `@AfterInsert`[​](#afterinsert "Direct link to afterinsert")

You can define a method with any name in entity and mark it with `@AfterInsert` and TypeORM will call it after the entity is inserted using repository/manager `save`. Example:

```
@Entity()

export class Post {

    @AfterInsert()

    resetCounters() {

        this.counters = 0

    }

}
```

### `@BeforeUpdate`[​](#beforeupdate "Direct link to beforeupdate")

You can define a method with any name in the entity and mark it with `@BeforeUpdate` and TypeORM will call it before an existing entity is updated using repository/manager `save`. Keep in mind, however, that this will occur only when information is changed in the model. If you run `save` without modifying anything from the model, `@BeforeUpdate` and `@AfterUpdate` will not run. Example:

```
@Entity()

export class Post {

    @BeforeUpdate()

    updateDates() {

        this.updatedDate = new Date()

    }

}
```

### `@AfterUpdate`[​](#afterupdate "Direct link to afterupdate")

You can define a method with any name in the entity and mark it with `@AfterUpdate` and TypeORM will call it after an existing entity is updated using repository/manager `save`. Example:

```
@Entity()

export class Post {

    @AfterUpdate()

    updateCounters() {

        this.counter = 0

    }

}
```

### `@BeforeRemove`[​](#beforeremove "Direct link to beforeremove")

You can define a method with any name in the entity and mark it with `@BeforeRemove` and TypeORM will call it before an entity is removed using repository/manager `remove`. Example:

```
@Entity()

export class Post {

    @BeforeRemove()

    updateStatus() {

        this.status = "removed"

    }

}
```

### `@AfterRemove`[​](#afterremove "Direct link to afterremove")

You can define a method with any name in the entity and mark it with `@AfterRemove` and TypeORM will call it after the entity is removed using repository/manager `remove`. Example:

```
@Entity()

export class Post {

    @AfterRemove()

    updateStatus() {

        this.status = "removed"

    }

}
```

### `@BeforeSoftRemove`[​](#beforesoftremove "Direct link to beforesoftremove")

You can define a method with any name in the entity and mark it with `@BeforeSoftRemove` and TypeORM will call it before an entity is soft removed using repository/manager `softRemove`. Example:

```
@Entity()

export class Post {

    @BeforeSoftRemove()

    updateStatus() {

        this.status = "soft-removed"

    }

}
```

### `@AfterSoftRemove`[​](#aftersoftremove "Direct link to aftersoftremove")

You can define a method with any name in the entity and mark it with `@AfterSoftRemove` and TypeORM will call it after the entity is soft removed using repository/manager `softRemove`. Example:

```
@Entity()

export class Post {

    @AfterSoftRemove()

    updateStatus() {

        this.status = "soft-removed"

    }

}
```

### `@BeforeRecover`[​](#beforerecover "Direct link to beforerecover")

You can define a method with any name in the entity and mark it with `@BeforeRecover` and TypeORM will call it before an entity is recovered using repository/manager `recover`. Example:

```
@Entity()

export class Post {

    @BeforeRecover()

    updateStatus() {

        this.status = "recovered"

    }

}
```

### `@AfterRecover`[​](#afterrecover "Direct link to afterrecover")

You can define a method with any name in the entity and mark it with `@AfterRecover` and TypeORM will call it after the entity is recovered using repository/manager `recover`. Example:

```
@Entity()

export class Post {

    @AfterRecover()

    updateStatus() {

        this.status = "recovered"

    }

}
```

## What is a Subscriber?[​](#what-is-a-subscriber "Direct link to What is a Subscriber?")

Marks a class as an event subscriber which can listen to specific entity events or any entity events. Events are firing using `QueryBuilder` and repository/manager methods. Example:

```
@EventSubscriber()

export class PostSubscriber implements EntitySubscriberInterface<Post> {

    /**

     * Indicates that this subscriber only listen to Post events.

     */

    listenTo() {

        return Post

    }



    /**

     * Called before post insertion.

     */

    beforeInsert(event: InsertEvent<Post>) {

        console.log(`BEFORE POST INSERTED: `, event.entity)

    }

}
```

You can implement any method from `EntitySubscriberInterface`. To listen to any entity you just omit `listenTo` method and use `any`:

```
@EventSubscriber()

export class PostSubscriber implements EntitySubscriberInterface {

    /**

     * Called after entity is loaded.

     */

    afterLoad(entity: any) {

        console.log(`AFTER ENTITY LOADED: `, entity)

    }



    /**

     * Called before query execution.

     */

    beforeQuery(event: BeforeQueryEvent) {

        console.log(`BEFORE QUERY: `, event.query)

    }



    /**

     * Called after query execution.

     */

    afterQuery(event: AfterQueryEvent) {

        console.log(`AFTER QUERY: `, event.query)

    }



    /**

     * Called before entity insertion.

     */

    beforeInsert(event: InsertEvent<any>) {

        console.log(`BEFORE ENTITY INSERTED: `, event.entity)

    }



    /**

     * Called after entity insertion.

     */

    afterInsert(event: InsertEvent<any>) {

        console.log(`AFTER ENTITY INSERTED: `, event.entity)

    }



    /**

     * Called before entity update.

     */

    beforeUpdate(event: UpdateEvent<any>) {

        console.log(`BEFORE ENTITY UPDATED: `, event.entity)

    }



    /**

     * Called after entity update.

     */

    afterUpdate(event: UpdateEvent<any>) {

        console.log(`AFTER ENTITY UPDATED: `, event.entity)

    }



    /**

     * Called before entity removal.

     */

    beforeRemove(event: RemoveEvent<any>) {

        console.log(

            `BEFORE ENTITY WITH ID ${event.entityId} REMOVED: `,

            event.entity,

        )

    }



    /**

     * Called after entity removal.

     */

    afterRemove(event: RemoveEvent<any>) {

        console.log(

            `AFTER ENTITY WITH ID ${event.entityId} REMOVED: `,

            event.entity,

        )

    }



    /**

     * Called before entity removal.

     */

    beforeSoftRemove(event: SoftRemoveEvent<any>) {

        console.log(

            `BEFORE ENTITY WITH ID ${event.entityId} SOFT REMOVED: `,

            event.entity,

        )

    }



    /**

     * Called after entity removal.

     */

    afterSoftRemove(event: SoftRemoveEvent<any>) {

        console.log(

            `AFTER ENTITY WITH ID ${event.entityId} SOFT REMOVED: `,

            event.entity,

        )

    }



    /**

     * Called before entity recovery.

     */

    beforeRecover(event: RecoverEvent<any>) {

        console.log(

            `BEFORE ENTITY WITH ID ${event.entityId} RECOVERED: `,

            event.entity,

        )

    }



    /**

     * Called after entity recovery.

     */

    afterRecover(event: RecoverEvent<any>) {

        console.log(

            `AFTER ENTITY WITH ID ${event.entityId} RECOVERED: `,

            event.entity,

        )

    }



    /**

     * Called before transaction start.

     */

    beforeTransactionStart(event: TransactionStartEvent) {

        console.log(`BEFORE TRANSACTION STARTED: `, event)

    }



    /**

     * Called after transaction start.

     */

    afterTransactionStart(event: TransactionStartEvent) {

        console.log(`AFTER TRANSACTION STARTED: `, event)

    }



    /**

     * Called before transaction commit.

     */

    beforeTransactionCommit(event: TransactionCommitEvent) {

        console.log(`BEFORE TRANSACTION COMMITTED: `, event)

    }



    /**

     * Called after transaction commit.

     */

    afterTransactionCommit(event: TransactionCommitEvent) {

        console.log(`AFTER TRANSACTION COMMITTED: `, event)

    }



    /**

     * Called before transaction rollback.

     */

    beforeTransactionRollback(event: TransactionRollbackEvent) {

        console.log(`BEFORE TRANSACTION ROLLBACK: `, event)

    }



    /**

     * Called after transaction rollback.

     */

    afterTransactionRollback(event: TransactionRollbackEvent) {

        console.log(`AFTER TRANSACTION ROLLBACK: `, event)

    }

}
```

Make sure your `subscribers` property is set in your [DataSourceOptions](https://typeorm.io/docs/data-source/data-source-options.md#common-data-source-options) so TypeORM loads your subscriber.

### `Event Object`[​](#event-object "Direct link to event-object")

Excluding `listenTo`, all `EntitySubscriberInterface` methods are passed an event object that has the following base properties:

* `dataSource: DataSource` - DataSource used in the event.
* `queryRunner: QueryRunner` - QueryRunner used in the event transaction.
* `manager: EntityManager` - EntityManager used in the event transaction.

See each [Event's interface](https://github.com/typeorm/typeorm/tree/master/src/subscriber/event) for additional properties.

Note that `event.entity` may not necessarily contain primary key(s) when `Repository.update()` is used. Only the values provided as the entity partial will be available. In order to make primary keys available in the subscribers, you can explicitly pass primary key value(s) in the partial entity object literal or use `Repository.save()`, which performs re-fetching.

```
await postRepository.update(post.id, { description: "Bacon ipsum dolor amet cow" })



// post.subscriber.ts

afterUpdate(event: UpdateEvent<Post>) {

  console.log(event.entity) // outputs { description: 'Bacon ipsum dolor amet cow' }

}
```

**Note:** All database operations in the subscribed event listeners should be performed using the event object's `queryRunner` or `manager` instance.
