All files / modules events.ts

100% Statements 11/11
100% Branches 1/1
100% Functions 4/4
100% Lines 9/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 751x 1x                                                         1x         5x                     10x 5x   10x                       6x                     4x    
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
 
/**
 * A global event bus service for Angular applications.
 * This service allows components and services to communicate 
 * with each other through event-based messaging without direct dependencies.
 * 
 * ### Features:
 * - **Global event handling**: Any component or service can emit or subscribe to events.
 * - **Loose coupling**: Components and services do not need to be aware of each other.
 * - **Efficient event subscription**: Uses a `Map` of subjects to optimize performance.
 * - **Type safety**: Supports TypeScript generics for strongly-typed event data.
 * 
 * ### Example Usage:
 * #### Emitting an event:
 * ```typescript
 * this.eventBusService.emit('userLoggedIn', { id: 1, name: 'John Doe' });
 * ```
 * 
 * #### Subscribing to an event:
 * ```typescript
 * this.eventBusService.on<{ id: number; name: string }>('userLoggedIn').subscribe(user => {
 *   console.log('User logged in:', user);
 * });
 * ```
 */
@Injectable({
    providedIn: 'root'
})
export class eventbusService {
    /** 
     * A map to store subjects for each event type.
     * Each event name is associated with a `Subject` to allow multiple subscriptions.
     */    
    private subjects: Map<string, Subject<any>> = new Map();
  
    /**
     * Retrieves or creates a `Subject` for the specified event.
     * If the event does not exist in the map, a new `Subject` is created.
     * 
     * @template T - The data type expected for the event.
     * @param event - The name of the event.
     * @returns The `Subject` associated with the event.
     */    
    private getSubject<T>(event: string): Subject<T> {
        if (!this.subjects.has(event)) {
            this.subjects.set(event, new Subject<T>());
        }
        return this.subjects.get(event) as Subject<T>;
    }
  
    /**
     * Emits an event with associated data.
     * All subscribers to this event will receive the data.
     * 
     * @template T - The data type associated with the event.
     * @param event - The name of the event.
     * @param data - The data to be sent with the event.
     */    
    emit<T>(event: string, data: T): void {
        this.getSubject<T>(event).next(data);
    }
  
    /**
     * Subscribes to a specific event and listens for emitted data.
     * 
     * @template T - The expected data type for the event.
     * @param event - The name of the event to subscribe to.
     * @returns An `Observable` that emits data when the event occurs.
     */    
    on<T>(event: string): Observable<T> {
        return this.getSubject<T>(event).asObservable();
    }
}