In several use cases, I find the event bus pattern to be very effective. Angular signals provide an excellent mechanism for managing state, so I decided to implement the event bus pattern using Angular signals.
In my recent project, I am developing a dashboard where the widgets need to communicate with each other while remaining standalone. Each widget has its own state and API, making the event bus pattern a perfect fit for this scenario.
EventBus
Example
Publish banana to the EventBus
import { SignalBusService } from 'ng-signal-bus'
@Component({
selector: 'app-widget-add-grocery-items',
standalone: true,
})
export class WidgetAddGroceryItemsComponent {
signalBus = inject(SignalBusService)
constructor() {
this.publish('fruit:banana', 'Banana')
}
publish(key:string, data: any) {
this.signalBus.publish(key, data)
}
}
Subscribe to the eventBus and listen for all fruits with the fruit:*
selector.
import { SignalBusService } from 'ng-signal-bus'
@Component({
selector: 'app-widget-fruit-list',
standalone: true,
})
export class WidgetFruitListComponent {
signalBus = inject(SignalBusService)
ngOnInit() {
this.signalBus.subscribe('fruit:*', (metaData) => {
// Outputs { data: 'Banana', timestamp: 1434342 }
console.log(metaData);
});
}
}
metaData
Inside the subscribe callback the service returns a metaData object
export interface MetaData {
data: any;
timestamp: number;
}
In this example, we use a simple string as the payload, but you can also provide an object.
this.publish('fruit:banana', { name: 'Banana', amount: 4 } )
// output
{
data: { name: 'Banana', amount: 4 }
timestamp: 232322
}
Demo
Full demo see Stackblitz
Package
I have packaged the SignalBusService into an NPM package, so you can easily use it in your project.
Angular Signal
Under the hood it's using a signal to store and mutate data, the effect() calls the callback function to update subscribers.
Note: Only tested with Angular v18.
Top comments (0)