Let's think about this for a moment
Building on the structure from Part 1, in Part 2 we'll add the app's core feature: task add/list/toggle functionality. The services, dependency injection, reactive forms, *ngFor directive, and two-way binding lessons are all foundational for this stage. We'll centralize a single TaskService to share data between components, managing the task list with a BehaviorSubject. This keeps component logic simple and reusable.
Let's build it for real
Create `TaskService` with `ng generate service task`, and implement three methods — `getTasks()`, `addTask(task)`, `toggleComplete(id)` — around an internal BehaviorSubject<Task[]>. In TaskListComponent, build a FormGroup (title, description) for adding a new task, and call service.addTask() on submit. Loop over the task list with *ngFor, and wire up each checkbox with [(ngModel)] to toggle completed status. Give completed tasks a strikethrough style with ngClass.
Code Example
// task.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { Task } from './task.model';
@Injectable({ providedIn: 'root' })
export class TaskService {
private tasksSubject = new BehaviorSubject<Task[]>([]);
tasks$ = this.tasksSubject.asObservable();
private nextId = 1;
getTasks() {
return this.tasks$;
}
addTask(title: string, description: string) {
const current = this.tasksSubject.value;
const newTask: Task = { id: this.nextId++, title, description, completed: false };
this.tasksSubject.next([...current, newTask]);
}
toggleComplete(id: number) {
const updated = this.tasksSubject.value.map(t =>
t.id === id ? { ...t, completed: !t.completed } : t
);
this.tasksSubject.next(updated);
}
}Typing a task's title/description into the form and submitting it instantly adds a new task to the list, and clicking the checkbox switches it to a strikethrough style.5-Minute Try-It
Within 5 minutes, add a deleteTask(id) method to TaskService and wire it up to a delete button in TaskListComponent.
A Quick Word of Caution
Change detection will work correctly if you avoid mutating service state directly from within a component, and instead return a new reference via Subject.next().