Lesson 22-NestJS Events

Event Dispatching and Listening

NestJS supports event-driven programming through the @nestjs/microservices and @nestjs/websockets modules. For simple in-application event dispatching, you can use the built-in @nestjs/messaging (based on an in-memory message queue) or a custom event emitter.

Using EventEmitter
NestJS’s built-in EventEmitter class can be used for straightforward communication between components.

import { Injectable, OnModuleInit, EventEmitter2 } from '@nestjs/common';

@Injectable()
export class EventsService implements OnModuleInit {
  constructor(private eventEmitter: EventEmitter2) {}

  onModuleInit() {
    this.eventEmitter.emit('app:start', { message: 'Application started.' });
  }
}

@Injectable()
export class SomeOtherService {
  constructor(private eventEmitter: EventEmitter2) {
    this.eventEmitter.on('app:start', (data) => {
      console.log(data);
    });
  }
}

Listening to Events

Listening to events involves subscribing to specific events and executing corresponding logic when the event occurs.

import { Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';

@Injectable()
export class ListenerService {
  constructor(private eventEmitter: EventEmitter2) {
    this.eventEmitter.on('app:start', (data) => {
      console.log('Listener Service:', data);
    });
  }
}

Using Message Queues
For more complex requirements, you can use message queue services like RabbitMQ or Kafka with the @nestjs/microservices module to implement event publishing and subscription.

Server-Sent Events (SSE)

Server-Sent Events (SSE) is a technology that enables the server to push data to the browser proactively, suitable for real-time update scenarios such as stock prices or chat messages.

Implementing SSE
Controller example:

import { Controller, Get, Response, StreamableFile } from '@nestjs/common';
import { interval } from 'rxjs';
import { map } from 'rxjs/operators';

@Controller('sse')
export class SseController {
  @Get()
  getSse(@Response({ passthrough: true }) res) {
    res.header('Content-Type', 'text/event-stream');
    res.header('Cache-Control', 'no-cache');
    res.header('Connection', 'keep-alive');

    const stream$ = interval(1000).pipe(
      map(i => `id: ${i}\ndata: ${new Date().toLocaleTimeString()}\n\n`),
    );

    return new StreamableFile(stream$.subscribe(data => res.write(data)));
  }
}

This code creates an SSE stream that sends the current time to the client every second until the connection is closed.

Share your love