Sitemap

Building Dynamic Tree Structures in Angular with the Composite Design Pattern

4 min readMay 25, 2025

--

Design patterns are the secret sauce that makes complex software solutions more scalable, flexible, and maintainable. One powerful pattern is the Composite Design Pattern, especially useful when working with tree-like structures in Angular applications.

Let’s dive in!

🎯 1️⃣ Composite Design Pattern

The Composite Design Pattern lets you treat individual objects and compositions of objects uniformly. It’s perfect for structures like trees, where leaves (single items) and composites (collections of items) should be handled similarly.

Press enter or click to view image in full size
Composite Pattern (Image Source)

The key components of this pattern:
✅ Component — an interface or abstract class that defines common operations for all nodes
✅ Leaf — represents individual objects (end nodes) that don’t have children
✅ Composite — represents nodes that can have children and implement child-related operations

In TypeScript, you typically define a common interface or abstract class (Component) and then create concrete Leaf and Composite classes that implement or extend it.

🛠️ 2️⃣ Uses of Design Patterns

Design patterns help solve common problems in software development by:

✅ Providing standard solutions
✅ Making code more readable and reusable
✅ Improving communication among team members
✅ Enabling consistent architecture

Patterns like Composite are widely used in UI components, file systems, and document structures.

🚀 3️⃣ Scalability, Flexibility, Maintainability

Here’s why design patterns are so valuable:

🔹 Scalability: Patterns provide a solid foundation that’s easy to extend when new requirements emerge.

🔹 Flexibility: Patterns separate concerns, making it easier to adapt or swap out parts of the system.

🔹 Maintainability: With clear structure and separation of responsibilities, the code is easier to understand and maintain over time.

🌳 4️⃣ Real Example: Creating a Tree in Angular using Composite Design Pattern

Get Shivam Vishvakarma’s stories in your inbox

Join Medium for free to get updates from this writer.

Let’s build a simple Tree Component in Angular that displays a hierarchical tree structure — a perfect use case for the Composite Design Pattern.

👇 4.1 Project Setup

We’ll use Agular's default setup. In your component folder, let’s start by defining a common interface:

// tree-item.ts
export interface TreeItem {
name: string;
display(indent: string): void;
}

🍃 4.2 Leaf Implementation

A Leaf is a single, standalone item in the tree.

// leaf.ts
import { TreeItem } from './tree-item';
export class Leaf implements TreeItem {
constructor(public name: string) {}
display(indent: string): void {
console.log(`${indent}- ${this.name}`);
}
}

🌿 4.3 Composite Implementation

A Composite contains children that can be either Leaf or Composite.

// composite.ts
import { TreeItem } from './tree-item';

export class Composite implements TreeItem {
private children: TreeItem[] = [];

constructor(public name: string) {}

add(item: TreeItem): void {
this.children.push(item);
}

remove(item: TreeItem): void {
this.children = this.children.filter(child => child !== item);
}

display(indent: string): void {
console.log(`${indent}+ ${this.name}`);
for (const child of this.children) {
child.display(indent + ' ');
}
}
}

🏗️ 4.4 Why Use the Composite Pattern Here?

👉 Uniformity: Whether it’s a Leaf or a Composite, both implement the same interface (TreeItem). This makes rendering or manipulating the tree super easy and consistent.

👉 Extensibility: Adding new node types or changing the display logic becomes much easier.

👉 Clear hierarchy: Each Composite knows how to display itself and its children, following the Single Responsibility Principle.

📦 4.5 Putting It All Together in Angular Component

// tree.component.ts
import { Component, OnInit } from '@angular/core';
import { Leaf } from './leaf';
import { Composite } from './composite';
import { TreeItem } from './tree-item';

@Component({
selector: 'app-tree',
template: `<h2>Tree Structure (Check Console)</h2>`,
})
export class TreeComponent implements OnInit {
root: Composite;

ngOnInit(): void {
this.root = new Composite('Root');

const branch1 = new Composite('Branch 1');
branch1.add(new Leaf('Leaf 1.1'));
branch1.add(new Leaf('Leaf 1.2'));

const branch2 = new Composite('Branch 2');
const subBranch = new Composite('Sub Branch 2.1');
subBranch.add(new Leaf('Leaf 2.1.1'));
branch2.add(subBranch);
branch2.add(new Leaf('Leaf 2.2'));

this.root.add(branch1);
this.root.add(branch2);

this.root.display('');
}
}

⚡ Explanation:

  • TreeComponent uses Composite and Leaf objects to build a dynamic tree.
  • Calling root.display('') triggers a recursive traversal of the tree, respecting the Composite pattern’s uniformity.
  • Console output will show the tree hierarchy neatly.

📝 5️⃣ Summary

✅ The Composite Design Pattern is perfect for tree structures in Angular.
✅ It ensures uniform treatment of leaves and composites.
✅ It improves scalability by allowing new types of nodes.
✅ It enhances flexibility and maintainability by isolating responsibilities and leveraging TypeScript’s interfaces and class hierarchy.

📦 What’s Next?
👉 In the next blog, we’ll share the complete GitHub repo and folder structure, along with best practices for implementing the Composite Design Pattern in an Angular project. Stay tuned!

🎉 Final Thoughts
The Composite Design Pattern in Angular makes your components more modular, testable, and future-proof — a perfect example of how design patterns can elevate your projects.
Got questions? Drop them below! 👇
Follow for more Angular insights, and let’s build clean, scalable apps together! 🚀

--

--

Shivam Vishvakarma
Shivam Vishvakarma

Written by Shivam Vishvakarma

Hey, I'm Passionate about .Net, Angular, SQL, and Cloud tech. Join my coding journey! 🚀 Let's connect!