Angular signal based message/event bus service for Angular. 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.
- Communication between component without a state library, just straightforward communication.
- Widget A updates Widgets B anywhere in the application
- Logger
npm install --save ng-signal-bus
import { SignalBusService } from 'ng-signal-bus'
@Component({
selector: 'app-widget-add-grocery-items',
standalone: true,
})
export class WidgetAddGroceryItemsComponent {
signalBus = inject(SignalBusService)
}
import { SignalBusService } from 'ng-signal-bus'
@Component({
selector: 'app-widget-add-grocery-items',
standalone: true,
})
export class WidgetAddGroceryItemsComponent {
signalBus = inject(SignalBusService)
constructor() {
this.publish('grocerylist:add', 'Banana')
}
publish(key:string, data: any) {
this.signalBus.publish(key, data)
}
}
import { SignalBusService } from 'ng-signal-bus'
@Component({
selector: 'app-widget-add-grocery-items',
standalone: true,
})
export class WidgetAddGroceryItemsComponent {
signalBus = inject(SignalBusService)
ngOnInit() {
this.signalBus.subscribe('grocerylist:add', (metaData) => {
// Outputs { data: 'Banana', timestamp: 1434342 }
console.log(metaData);
});
}
}
The callback function runs in the effect() excecution context which not allow to update/write to any signals. To allow this, untracked is used. Untracked will run the function without creating dependencies.
untracked(() => callback(data.metaData));
import { model } from '@angular/core';
items = model<Item[]>([]);
addItem(title: string = '') {
this.items.update((items: Item[]) => {
return [...items, { title }];
});
}
ngOnInit() {
this.signalBus.subscribe('*', (metaData) => {
this.addItem(metaData.data);
});
}