Angular › New Control Flow Syntax (@if, @for & @switch)

How does the new at for control flow block work, and why does it require a track expression?

Beginner

Answer

The at for block repeats a piece of template content for every item in a list, similar to the older ngFor directive, but it requires a track expression, telling Angular exactly how to identify each item uniquely, which helps Angular efficiently update the list when items are added, removed, or reordered.
@Component({
  selector: 'app-todo-list',
  template: `
    @for (todo of todos; track todo.id) {
      <li>{{ todo.text }}</li>
    } @empty {
      <li>No tasks yet</li>
    }
  `
})
export class TodoListComponent {
  todos: { id: number; text: string }[] = [];
}
Real-world example A to do list app displays every task using the at for block, tracking each item by its unique id, and automatically shows a friendly empty state message using the at empty block when there are no tasks at all.

Common follow-ups: What happens if you use track index instead of a unique property from your data?;What does the at empty block specifically handle that the older ngFor did not support directly?