Notifications
Hosanna provides a lightweight publish/subscribe system for app-wide notifications. You can listen using the @onNotification
decorator (auto-managed lifecycle) or manually subscribe/unsubscribe for full control. Notifications are generically typed for strongly-typed payloads.
API overview
export interface INotification<T = undefined> { name: string; data: T }
export type onNotification<T = undefined> = (notification: INotification<T>) => void;
export function onNotification(notificationName: string) { /* decorator registering handlers */ }
export interface INotificationCenter {
dispatch(notification: INotification<any>): void;
subscribe(name: string, handler: onNotification<any>): IIdentifiable;
unsubscribe(name: string, handler: onNotification<any> | IIdentifiable): void;
}
export class HsNotification<T = undefined> implements INotification<T> {
constructor(name: string, data?: T) { /* ... */ }
dispatch() { AppUtils.resolve<INotificationCenter>('notificationCenter').dispatch(this); }
}
Decorator subscriptions are automatically toggled when a view enters/leaves the view hierarchy via internal hooks:
export function toggleNotificationSubscription(target: INotificationClient, active: boolean) {
if (!target.notificationHandlers) return;
const notificationCenter = AppUtils.resolve<INotificationCenter>('notificationCenter');
for (const { name, handler } of target.notificationHandlers) {
if (active) notificationCenter.subscribe(name, handler.bind(target));
else notificationCenter.unsubscribe(name, handler);
}
}
Sending notifications
enum SampleNotificationType { First = 'first', Second = 'second' }
new HsNotification<JsonData>(SampleNotificationType.First).dispatch();
new HsNotification<JsonData>(SampleNotificationType.Second).dispatch();
Receiving notifications (decorators)
@onNotification(SampleNotificationType.First)
onFirstNotification(notification: HsNotification<JsonData>) {
this.numberOfFirstNotificationsReceived++;
}
@onNotification(SampleNotificationType.Second)
onSecondNotification(notification: HsNotification<JsonData>) {
this.numberOfSecondNotificationsReceived++;
}
Notes:
- Decorator-based handlers are auto-subscribed when the view is mounted and auto-unsubscribed when it is removed from the view hierarchy.
- This is ideal for view-scoped listeners.
Receiving notifications (manual subscribe/unsubscribe)
Manual control lets you subscribe anywhere (services, long-lived views) and decide when to unsubscribe.
const nc = AppUtils.resolve<INotificationCenter>('notificationCenter');
const handler: onNotification<MyPayload> = (n) => { /* handle n.data */ };
const token = nc.subscribe('my-event', handler);
// later
nc.unsubscribe('my-event', handler); // or pass token
Best practices
- Prefer decorators for view-local subscriptions that should follow view mount/unmount.
- Use manual subscribe/unsubscribe for app-wide or service-level listeners.
- Define string constants/enums for notification names.
- Use generic payloads for type safety:
HsNotification<MyType>(name, data)
.