@nestbolt/taggable
Events
Listen to tag lifecycle events via @nestjs/event-emitter.
Overview
When @nestjs/event-emitter is installed, @nestbolt/taggable emits events for tag creation, deletion, attachment, and detachment. This lets you react to tag changes across your application.
If @nestjs/event-emitter is not installed, the package works normally but no events are emitted.
Setup
Install and register the event emitter:
npm install @nestjs/event-emitterimport { EventEmitterModule } from "@nestjs/event-emitter";
@Module({
imports: [
EventEmitterModule.forRoot(),
TaggableModule.forRoot(),
],
})
export class AppModule {}Events
| Event | Constant | Payload | When |
|---|---|---|---|
tag.created | TAGGABLE_EVENTS.TAG_CREATED | TagCreatedEvent | After a tag is created |
tag.deleted | TAGGABLE_EVENTS.TAG_DELETED | TagDeletedEvent | After a tag is deleted |
tag.attached | TAGGABLE_EVENTS.TAG_ATTACHED | TagAttachedEvent | After a tag is attached to an entity |
tag.detached | TAGGABLE_EVENTS.TAG_DETACHED | TagDetachedEvent | After a tag is detached from an entity |
Event Payloads
TagCreatedEvent
interface TagCreatedEvent {
tag: TagEntity;
}TagDeletedEvent
interface TagDeletedEvent {
tagId: string;
tagName: string;
}TagAttachedEvent
interface TagAttachedEvent {
tag: TagEntity;
taggableType: string;
taggableId: string;
}TagDetachedEvent
interface TagDetachedEvent {
tagId: string;
taggableType: string;
taggableId: string;
}Listening to Events
Use the @OnEvent() decorator from @nestjs/event-emitter:
import { Injectable } from "@nestjs/common";
import { OnEvent } from "@nestjs/event-emitter";
import {
TAGGABLE_EVENTS,
TagCreatedEvent,
TagAttachedEvent,
TagDeletedEvent,
TagDetachedEvent,
} from "@nestbolt/taggable";
@Injectable()
export class TagEventListener {
@OnEvent(TAGGABLE_EVENTS.TAG_CREATED)
handleTagCreated(event: TagCreatedEvent) {
console.log(`New tag created: ${event.tag.name}`);
}
@OnEvent(TAGGABLE_EVENTS.TAG_ATTACHED)
handleTagAttached(event: TagAttachedEvent) {
console.log(
`Tag "${event.tag.name}" attached to ${event.taggableType}#${event.taggableId}`,
);
}
@OnEvent(TAGGABLE_EVENTS.TAG_DETACHED)
handleTagDetached(event: TagDetachedEvent) {
console.log(
`Tag ${event.tagId} detached from ${event.taggableType}#${event.taggableId}`,
);
}
@OnEvent(TAGGABLE_EVENTS.TAG_DELETED)
handleTagDeleted(event: TagDeletedEvent) {
console.log(`Tag deleted: ${event.tagName} (${event.tagId})`);
}
}Remember to register your listener as a provider in a module:
@Module({
providers: [TagEventListener],
})
export class AppModule {}Example: Invalidate Cache on Tag Change
@Injectable()
export class TagCacheInvalidator {
constructor(private readonly cacheManager: Cache) {}
@OnEvent(TAGGABLE_EVENTS.TAG_ATTACHED)
@OnEvent(TAGGABLE_EVENTS.TAG_DETACHED)
async invalidateEntityCache(event: TagAttachedEvent | TagDetachedEvent) {
const cacheKey = `${event.taggableType}:${event.taggableId}:tags`;
await this.cacheManager.del(cacheKey);
}
}Event Constants
All event names are available as constants to avoid typos:
import { TAGGABLE_EVENTS } from "@nestbolt/taggable";
TAGGABLE_EVENTS.TAG_CREATED; // "tag.created"
TAGGABLE_EVENTS.TAG_DELETED; // "tag.deleted"
TAGGABLE_EVENTS.TAG_ATTACHED; // "tag.attached"
TAGGABLE_EVENTS.TAG_DETACHED; // "tag.detached"