Singleton Broadcaster in Angular2

A simple way to subscribe and/or broadcast from anywhere in an app to anywhere else.

Basically, I needed a simple way to send out global messages not knowing what components would be loaded and didn't want to deal with injecting this anywhere in older components.  With a little messing around with some online guides (sorry I don't remember which ones) I came up with the following:

broadcast.service.ts
import { Injectable } from "@angular/core";
import { Subject } from "rxjs/Subject";

@Injectable()
export class BroadcastService {

    static instance: BroadcastService;
    static isCreating: Boolean = false;

    private broadcastMessageSource = new Subject<string>();
    broadcastMessage$ = this.broadcastMessageSource.asObservable();
    
    constructor() {
        if (!BroadcastService.isCreating) {
            throw new Error("You can't call new in Singleton instances");
        }
    }

    static getInstance() {
        if (BroadcastService.instance == null) {
            BroadcastService.isCreating = true;
            BroadcastService.instance = new BroadcastService();
            BroadcastService.isCreating = false;
        }
        return BroadcastService.instance;
    }

    broadcastMessage(modal: string) {
        this.broadcastMessageSource.next(modal);
    }
}

Then simply make sure to import it where you need it, and send out a broadcast:

BroadcastService.getInstance().broadcastMessage('message-i-care-about');

Where you need to,  subscribe in the constructor (or ngOnInit):

BroadcastService.getInstance().broadcastMessage$.subscribe(this.receiveBroadcastMessage.bind(this));

And deal with the broadcast however you will:

receiveBroadcastMessage(broadcast: string): void {
    console.log('broadcast received: ' + broadcast);

    // I generally run it through a switch to see if its something this component cares about
    switch (broadcast) { 
        case 'message-i-care-about': doSomething(); break;
    }
    // or just ignore it
}

There you go, just sent and received a global broadcast message.

Comments are closed