Coding exercise: create a shopping cart in Angular.
Model answer
Put the cart in an injectable service so every component sees the same state. Store it in a signal and derive the count and total with computed.
@Injectable({ providedIn: 'root' })
export class CartService {
private lines = signal<{ id: number; name: string; price: number; qty: number }[]>([]);
items = this.lines.asReadonly();
count = computed(() => this.lines().reduce((n, l) => n + l.qty, 0));
total = computed(() => this.lines().reduce((s, l) => s + l.price * l.qty, 0));
add(p: { id: number; name: string; price: number }) {
this.lines.update((ls) =>
ls.some((l) => l.id === p.id) ? ls.map((l) => (l.id === p.id ? { ...l, qty: l.qty + 1 } : l)) : [...ls, { ...p, qty: 1 }]);
}
remove(id: number) { this.lines.update((ls) => ls.filter((l) => l.id !== id)); }
}
@Component({
selector: 'app-cart',
template: `
<ul>@for (l of cart.items(); track l.id) {
<li>{{ l.name }} × {{ l.qty }} <button (click)="cart.remove(l.id)">Remove</button></li>
}</ul>
<p>Total: {{ cart.total() }}</p>`,
})
export class CartView { cart = inject(CartService); }Exposing asReadonly stops components changing the list directly. Save the cart to localStorage with an effect, and always recheck prices on the server at checkout.
Tips
- Mention NgRx or the signal store when the state gets large.
Practise it yourself in the React and Angular code playground.
Learn this topic
Angular Tutorial: Beginner to Advanced .
Sign in to add your own answer.
More questions
- Coding exercise: build a Todo application in Angular.
- Coding exercise: create a search box with debounce in Angular.
- Coding exercise: fetch API data and display it in a table in Angular.
- Coding exercise: implement pagination in Angular.
- Coding exercise: create a login form with validation in Angular.
- Coding exercise: build a parent-child communication example in Angular.