Lab 15: Signal Cart Refactor
π Resourcesβ
π Starter Codeβ
step-15-album-wholesale-v21-post-signal-computed
In this lab, you'll refactor your shopping cart service from observables to signals. You'll replace BehaviorSubject with signal(), use update() for immutable state changes, and implement computed signals for cart totals.
π Instructionsβ
Step 1: Create Signal-Based Cartβ
Replace Observable-based cart with signals:
@Injectable({ providedIn: 'root' })
export class CartService {
// Private writable signal
private cart = signal<Album[]>([]);
// Public computed
cartItems = computed(() => this.cart());
add(album: Album) {
this.cart.update(items => [...items, album]);
}
remove(albumId: number) {
this.cart.update(items => items.filter(item => item.id !== albumId));
}
}
Step 2: Use Computed for Derived Stateβ
Create computed signals for totals:
export class CartComponent {
cartService = inject(CartService);
totalItems = computed(() => this.cartService.cartItems().length);
totalPrice = computed(() =>
this.cartService.cartItems().reduce((sum, item) => sum + item.price, 0)
);
}
Step 3: Update Cart with Immutabilityβ
Use update() for immutable updates:
// Add item
this.cart.update(items => [...items, newItem]);
// Remove item
this.cart.update(items => items.filter(item => item.id !== id));
// Update item
this.cart.update(items =>
items.map(item => item.id === id ? { ...item, quantity: item.quantity + 1 } : item)
);