Skip to main content
StackDevLife
AngularintermediateMay 2, 2026

Angular Cheatsheet

Components, directives, services, pipes, routing, and RxJS patterns for Angular development.

Component Basics

Component decorator

@Component({
  selector: "app-hello",
  template: `<h1>Hello, {{ name }}</h1>`,
  standalone: true,
})
export class HelloComponent {
  name = "World";
}

Input & Output

@Input() title: string = "";
@Output() clicked = new EventEmitter<void>();

onButtonClick() {
  this.clicked.emit();
}

Lifecycle hooks

implements OnInit, OnDestroy

ngOnInit() { /* called once after init */ }
ngOnDestroy() { /* cleanup subscriptions */ }

ViewChild

@ViewChild("myInput") inputRef!: ElementRef;

ngAfterViewInit() {
  this.inputRef.nativeElement.focus();
}

Template Syntax

Interpolation

{{ title }}
{{ user.name | uppercase }}

Property binding

<img [src]="imageUrl" [alt]="title">

Event binding

<button (click)="handleClick($event)">Click</button>

Two-way binding

<input [(ngModel)]="username">

*ngIf (legacy)

<div *ngIf="isLoggedIn; else loginBlock">Welcome</div>
<ng-template #loginBlock>Please log in</ng-template>

@if (new control flow)

@if (isLoggedIn) {
  <p>Welcome!</p>
} @else {
  <p>Please log in.</p>
}

@for (new control flow)

@for (item of items; track item.id) {
  <li>{{ item.name }}</li>
}

Services & Dependency Injection

Create service

@Injectable({ providedIn: "root" })
export class UserService {
  constructor(private http: HttpClient) {}

  getUser(id: number): Observable<User> {
    return this.http.get<User>(`/api/users/${id}`);
  }
}

Inject into component

constructor(private userService: UserService) {}

// or with inject()
private userService = inject(UserService);

HttpClient

this.http.get<Post[]>("/api/posts");
this.http.post<Post>("/api/posts", body);
this.http.put<Post>(`/api/posts/${id}`, body);
this.http.delete(`/api/posts/${id}`);

RxJS Essentials

subscribe

this.userService.getUser(1).subscribe({
  next: (user) => this.user = user,
  error: (err) => console.error(err),
});

Common operators

import { map, filter, switchMap, takeUntil, catchError } from "rxjs/operators";

obs$.pipe(
  map(data => data.items),
  filter(items => items.length > 0),
  catchError(err => of([]))
).subscribe();

switchMap (cancel previous)

searchInput$.pipe(
  debounceTime(300),
  switchMap(query => this.search(query))
).subscribe(results => this.results = results);

Unsubscribe with takeUntil

private destroy$ = new Subject<void>();

obs$.pipe(takeUntil(this.destroy$)).subscribe();

ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}

Async pipe (preferred)

<ul>
  <li *ngFor="let item of items$ | async">{{ item.name }}</li>
</ul>

Async pipe auto-unsubscribes when component is destroyed.

Routing

Route config

const routes: Routes = [
  { path: "", component: HomeComponent },
  { path: "about", component: AboutComponent },
  { path: "post/:id", component: PostComponent },
  { path: "**", component: NotFoundComponent },
];

Router link

<a routerLink="/about" routerLinkActive="active">About</a>
<a [routerLink]="['/post', post.id]">Post</a>

Navigate programmatically

constructor(private router: Router) {}

this.router.navigate(['/dashboard']);
this.router.navigate(['/post', id]);

Read route params

constructor(private route: ActivatedRoute) {}

const id = this.route.snapshot.paramMap.get("id");
// or as observable:
this.route.paramMap.pipe(
  map(params => params.get("id"))
).subscribe(id => ...);

Lazy loading

{ path: "admin", loadChildren: () =>
    import("./admin/admin.module").then(m => m.AdminModule) }

Pipes

Built-in pipes

{{ name | uppercase }}
{{ name | lowercase }}
{{ price | currency:"USD" }}
{{ date | date:"mediumDate" }}
{{ value | json }}
{{ text | slice:0:100 }}

Custom pipe

@Pipe({ name: "truncate", standalone: true })
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit = 50): string {
    return value.length > limit ? value.slice(0, limit) + "…" : value;
  }
}
#components#services#rxjs#routing#directives