1.0.0 • Published 9 months ago
@ea-utilities/mediator v1.0.0
Mediator
Utility for the Mediator Pattern Mediator is a versatile class designed to streamline event-driven, asynchronous programming. It enables you to easily register, unregister, and invoke subscriber methods, making it ideal for managing WebSockets, Ajax calls, DOM events, or any other asynchronous operations. This class ensures your code remains maintainable and testable.
Why Use Mediator?
The primary use case for Mediator is to effortlessly bind elements to WebSocket callbacks. However, its applications extend far beyond that. You can utilize it as an event management system, to decouple ts functions, handle Ajax request callbacks, and more.
Dependencies
- @angular > 16
Usage
Events
- First create a class with required properties in constructor
- class have to extend from
IRequest - Decorate event using
@Event(name), name will be used in future module registers
import { IRequest, Event } from '@ea-utilities/mediator';
@Event("UserSavedEvent")
export class UserSavedEvent implements IRequest {
constructor(public userId: number) { }
}Handlers
- Create class handler with custom logic
- class have to extends
IRequestHandler<MyEvent>, whereMyEventis the class created previously - Implement/Override
handlemethod with custom login
import { IRequestHandler } from '@ea-utilities/mediator';
export class SendTextMessageWhenUserSavedHandler extends IRequestHandler<UserSavedEvent> {
public override handle(event: UserSavedEvent): void | Promise<void> {
console.log(`Sending message to user ${event.userId}`);
}
}Register
- Go to
app.config.tsand addprovideMediator(...args)
import { provideMediator } from '@ea-utilities/mediator';
provideMediator([
{
eventType: UserSavedEvent,
handlers: [ SendTextMessageWhenUserSavedHandler ]
}
])Usage
- Configure events, handlers and register (Previous steps)
- Go to component and inject Mediator
_mediator = inject(Mediator) - use
Mediator.dispatch(event)orMediator.dispatchSync(event), whereeventis that extendingIRequest - Optionally you can send options:
{ onError: callback }, to capture errors and perform them
Example
// events.ts
import { provideMediator, IRequest, IRequestHandler, Event } from '@ea-utilities/mediator'
@Event("UserSavedEvent")
export class UserSavedEvent implements IRequest {
constructor(public userId: number) { }
}
export class SendTextMessageWhenUserSavedHandler extends IRequestHandler<UserSavedEvent> {
public override handle(event: UserSavedEvent): void | Promise<void> {
console.log(`Sending message to user ${event.userId}`);
}
}
export class InformAdminWhenUserSavedHandler extends IRequestHandler<UserSavedEvent> {
public override handle(event: UserSavedEvent): void | Promise<void> {
console.log(`Admin notified about user ${event.userId} changes`);
}
}
export class UpdateExternalSystemWhenUserSavedHandler extends IRequestHandler<UserSavedEvent> {
public override handle(event: UserSavedEvent): void | Promise<void> {
console.log(`External sytem updated with userId ${event.userId} changes`);
}
}
export class ErrorUserSavedHandler extends IRequestHandler<UserSavedEvent> {
public override handle(event: UserSavedEvent): void | Promise<void> {
throw Error('ErrorUserSavedHandler from ErrorUserSavedHandler');
}
}//app.config.ts
import { provideMediator } from '@ea-utilities/mediator'
export const appConfig: ApplicationConfig = {
providers: [
...
provideMediator([
{
eventType: UserSavedEvent,
handlers: [
SendTextMessageWhenUserSavedHandler,
InformAdminWhenUserSavedHandler,
UpdateExternalSystemWhenUserSavedHandler,
ErrorUserSavedHandler
]
}
])
]
};//app.component.ts
import { Mediator } from '@ea-utilities/mediator'
export class AppComponent {
mediator = inject(Mediator);
saveUser() {
//logic for saving user
console.log('saving user');
//then dispatch user saved
const event = new UserSavedEvent(5);
this.mediator.dispatch(event, {
onError: (error, event1) => {
console.error(error, event1);
}
});
}
}1.0.0
9 months ago