We use cookies to enhance your experience on the site
CodeWorlds

Communication Between Components via Services

Services are an excellent way for components to communicate - like messengers between castles.

Example: Shared State Service

1import { Injectable, signal, computed } from '@angular/core';
2
3export interface CartItem {
4  id: number;
5  name: string;
6  quantity: number;
7  price: number;
8}
9
10@Injectable({ providedIn: 'root' })
11export class CartService {
12  // State as signals
13  private items = signal<CartItem[]>([]);
14
15  // Computed values
16  readonly cartItems = this.items.asReadonly();
17  readonly totalItems = computed(() =>
18    this.items().reduce((sum, item) => sum + item.quantity, 0)
19  );
20  readonly totalPrice = computed(() =>
21    this.items().reduce((sum, item) => sum + item.price * item.quantity, 0)
22  );
23
24  addItem(item: Omit<CartItem, 'quantity'>): void {
25    const existing = this.items().find(i => i.id === item.id);
26    if (existing) {
27      this.items.update(items =>
28        items.map(i => i.id === item.id
29          ? { ...i, quantity: i.quantity + 1 }
30          : i
31        )
32      );
33    } else {
34      this.items.update(items => [...items, { ...item, quantity: 1 }]);
35    }
36  }
37
38  removeItem(id: number): void {
39    this.items.update(items => items.filter(i => i.id !== id));
40  }
41
42  clearCart(): void {
43    this.items.set([]);
44  }
45}

Usage in Components

1// header.component.ts - displays the count
2@Component({
3  template: \`<span>🛒 {{ cartService.totalItems() }}</span>\`
4})
5export class HeaderComponent {
6  cartService = inject(CartService);
7}
8
9// product.component.ts - adds to cart
10@Component({
11  template: \`<button (click)="addToCart()">Add</button>\`
12})
13export class ProductComponent {
14  private cartService = inject(CartService);
15
16  addToCart(): void {
17    this.cartService.addItem({
18      id: this.product.id,
19      name: this.product.name,
20      price: this.product.price
21    });
22  }
23}
Go to CodeWorlds