Angular: Chain of Responsibility design pattern

Sagarnath S
3 min readJan 28, 2024
Angular: Design pattern

The Chain of Responsibility design pattern is a behavioral pattern where a request is passed through a chain of handlers, with each handler having the ability to either handle the request or pass it on to the next handler in the chain. In the context of Angular applications, you can implement this pattern to handle various tasks or actions in a flexible and decoupled manner.

This pattern can be implemented for email handlers to allow for flexible and modular handling of incoming emails. Here’s a basic example of how you can structure this using Angular services:

// email-handler.interface.ts
export interface EmailHandler {
setNextHandler(handler: EmailHandler): void;
handleEmail(email: any): void;
}

// spam-email-handler.ts
import { EmailHandler } from './email-handler.interface';

export class SpamEmailHandler implements EmailHandler {
private nextHandler: EmailHandler;

setNextHandler(handler: EmailHandler): void {
this.nextHandler = handler;
}

handleEmail(email: any): void {
if (email.isSpam) {
console.log("Handling spam email...");
// Handle the spam email
} else if (this.nextHandler) {
this.nextHandler.handleEmail(email);
} else {
console.log("No handler available for this email.");
}
}
}

// promotion-email-handler.ts
import { EmailHandler } from './email-handler.interface';

export class PromotionEmailHandler implements EmailHandler {
private nextHandler: EmailHandler;

setNextHandler(handler: EmailHandler): void {
this.nextHandler = handler;
}

handleEmail(email: any): void {
if (email.isPromotion) {
console.log("Handling promotion email...");
// Handle the promotion email
} else if (this.nextHandler) {
this.nextHandler.handleEmail(email);
} else {
console.log("No handler available for this email.");
}
}
}

// general-email-handler.ts
import { EmailHandler } from './email-handler.interface';

export class GeneralEmailHandler implements EmailHandler {
handleEmail(email: any): void {
console.log("Handling general email...");
// Handle the general email
}
}

// email-handler.service.ts
import { Injectable } from '@angular/core';
import { EmailHandler } from './email-handler.interface';
import { SpamEmailHandler } from './spam-email-handler';
import { PromotionEmailHandler } from './promotion-email-handler';
import { GeneralEmailHandler } from './general-email-handler';

@Injectable({
providedIn: 'root'
})
export class EmailHandlerService {
private spamHandler: EmailHandler;
private promotionHandler: EmailHandler;
private generalHandler: EmailHandler;

constructor() {
this.spamHandler = new SpamEmailHandler();
this.promotionHandler = new PromotionEmailHandler();
this.generalHandler = new GeneralEmailHandler();

// Set up the chain of responsibility
this.spamHandler.setNextHandler(this.promotionHandler);
this.promotionHandler.setNextHandler(this.generalHandler);
}

handleEmail(email: any): void {
this.spamHandler.handleEmail(email);
}
}

// app.component.ts
import { Component } from '@angular/core';
import { EmailHandlerService } from './email-handler.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private emailHandlerService: EmailHandlerService) {}

ngOnInit() {
// Simulate incoming emails
const spamEmail = { isSpam: true };
const promotionEmail = { isPromotion: true };
const generalEmail = {};

// Pass emails through the chain
this.emailHandlerService.handleEmail(spamEmail); // Output: Handling spam email...
this.emailHandlerService.handleEmail(promotionEmail); // Output: Handling promotion email...
this.emailHandlerService.handleEmail(generalEmail); // Output: Handling general email...
}
}

// app.component.html (just for testing)
<p>Check the console for output.</p>
  • We define three concrete email handlers (SpamEmailHandler, PromotionEmailHandler, GeneralEmailHandler) and an EmailHandler interface.
  • We have an EmailHandlerService which sets up the chain of responsibility and handles incoming emails.
  • In the AppComponent, we inject EmailHandlerService and simulate incoming emails in the ngOnInit method.

Remember to import necessary modules and include these files in your Angular project structure. This example demonstrates the use of the Chain of Responsibility pattern in an Angular application for handling different types of emails.

Thank you for reading if you have any doubts. drop the message in comments.

Follow me on Medium or LinkedIn to read more about Angular and TS!

--

--

Sagarnath S

Software Development Engineer - I @CareStack || Web Developer || Angular || ASP.Net Core || C# || TypeScript || HTML || CSS