Angular Cheat Sheet

Quick reference for Angular 17+ — standalone components, signals, templates, directives, routing, forms, pipes, and lifecycle hooks. All essential patterns in one page.

Components Templates & Directives Services & Dependency Injection Routing Forms Pipes Lifecycle Hooks

Components

@Component({ standalone: true, template: `...` }) Standalone component (Angular 17+)
@Component({ selector: "app-hero", templateUrl: "./hero.html" }) Component with external template
@Component({ imports: [CommonModule, RouterModule] }) Import dependencies in standalone component
@Input() title: string = "" Input property binding
@Input({ required: true }) id!: number Required input (Angular 16+)
@Output() clicked = new EventEmitter<string>() Output event emitter
input.required<string>() Signal-based required input (Angular 17+)
output<string>() Signal-based output (Angular 17+)
viewChild.required<ElementRef>("myEl") Signal-based view child query
changeDetection: ChangeDetectionStrategy.OnPush OnPush change detection for performance

Templates & Directives

{{ expression }} Interpolation binding
[property]="value" Property binding
(event)="handler($event)" Event binding
[(ngModel)]="name" Two-way binding
@if (condition) { ... } @else { ... } Built-in control flow (Angular 17+)
@for (item of items; track item.id) { ... } Built-in for loop with track (Angular 17+)
@switch (value) { @case (1) { ... } } Built-in switch (Angular 17+)
@defer { ... } @loading { ... } Deferrable views — lazy load blocks (Angular 17+)
<ng-content select="[header]" /> Content projection with selector
<ng-template #tpl let-item>...</ng-template> Reusable template reference

Services & Dependency Injection

@Injectable({ providedIn: "root" }) Tree-shakable singleton service
constructor(private http: HttpClient) {} Constructor injection
inject(HttpClient) Functional inject() — no constructor needed
{ provide: API_URL, useValue: "/api" } Value provider with InjectionToken
{ provide: Logger, useClass: FileLogger } Class provider — swap implementation
{ provide: DataService, useFactory: () => new DataService(inject(HttpClient)) } Factory provider
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } Multi provider for interceptors
provideHttpClient(withInterceptors([authInterceptor])) Functional HTTP interceptors (Angular 17+)

Routing

provideRouter(routes) Provide routes in app config (standalone)
{ path: "users/:id", component: UserComponent } Route with parameter
{ path: "admin", loadComponent: () => import("./admin") } Lazy-load standalone component
{ path: "shop", loadChildren: () => import("./shop/routes") } Lazy-load child routes
{ path: "**", component: NotFoundComponent } Wildcard / 404 route
{ path: "old", redirectTo: "new", pathMatch: "full" } Redirect route
const id = this.route.snapshot.paramMap.get("id") Read route param (snapshot)
this.route.paramMap.subscribe(p => p.get("id")) Observe route param changes
this.router.navigate(["/users", id]) Programmatic navigation
canActivate: [AuthGuard] Route guard for auth protection

Forms

FormsModule + [(ngModel)]="name" Template-driven form binding
fb.group({ name: ["", Validators.required] }) Reactive form group with FormBuilder
fb.nonNullable.group({ email: "" }) Non-nullable form builder (Angular 14+)
new FormControl("", { validators: Validators.email }) Form control with validator
form.get("name")?.value Read form control value
form.patchValue({ name: "Alice" }) Partial update of form values
form.valid / form.invalid / form.dirty Form state checks
Validators.compose([Validators.required, Validators.minLength(3)]) Compose multiple validators
<div *ngIf="name.errors?.required">Required</div> Show validation error message

Pipes

{{ price | currency:"USD" }} Currency formatting
{{ today | date:"yyyy-MM-dd" }} Date formatting
{{ name | uppercase }} Transform to uppercase
{{ name | lowercase }} Transform to lowercase
{{ text | slice:0:100 }} Slice string or array
{{ value | json }} JSON stringify for debugging
{{ data$ | async }} Subscribe to Observable in template
{{ items | keyvalue }} Iterate object as key-value pairs
@Pipe({ name: "truncate", standalone: true }) Custom standalone pipe

Lifecycle Hooks

ngOnInit() Component initialized — fetch data here
ngOnChanges(changes: SimpleChanges) Input property changed
ngOnDestroy() Cleanup subscriptions and listeners
ngAfterViewInit() View (and children) fully rendered
ngAfterContentInit() Projected content initialized
ngDoCheck() Custom change detection logic
effect(() => { console.log(this.count()) }) Signal effect — runs on signal change (Angular 17+)
computed(() => this.price() * this.qty()) Computed signal — derived reactive value (Angular 17+)
Step-by-Step Guide

How to Build a CSS Grid Layout

Read Guide →

More Cheat Sheets