Master Angular interviews with 45+ questions on RxJS, dependency injection, change detection, and modern Angular patterns.
Angular is a full opinionated framework (not a library) with built-in: routing, HTTP client, forms, DI system, animations, i18n. React and Vue are libraries requiring third-party solutions for these. Angular uses TypeScript exclusively. Trade-offs: more structure and conventions (better for large teams), steeper learning curve, larger bundle. Angular 17+ introduces standalone components, signals, and deferred loading.
Components are the building blocks: @Component decorator with selector, template, styles. Every component has a template (HTML), class (TypeScript logic), and optional styles. Components form a tree. Data flows down via @Input(), events bubble up via @Output() (EventEmitter). Standalone components (Angular 14+) don't need NgModule — the modern default. Use OnPush change detection for performance.
Angular has a hierarchical injector tree. Services decorated with @Injectable can be provided: root (singleton across app), module level, component level (new instance per component). Inject via constructor: constructor(private service: MyService). Use useClass, useValue, useFactory for custom providers. InjectionToken for non-class providers. Understand injector hierarchy to avoid memory leaks.
Default change detection: Angular checks every component on any async event. OnPush: checks only when Input references change, an event originates in the component, async pipe resolves, or markForCheck() called. OnPush dramatically improves performance in large apps. Use with immutable data and observables. ChangeDetectorRef.detectChanges() for manual trigger. Angular 17 signals provide fine-grained reactivity without manual CD management.
RxJS provides Observables for async data streams. Angular uses it throughout: HttpClient returns Observables, Router events, FormControl valueChanges, EventEmitter. Key operators: map, filter, mergeMap, switchMap (cancel previous), concatMap (queue), catchError, debounceTime, distinctUntilChanged, takeUntil. Always unsubscribe to prevent leaks: async pipe (auto-unsubscribes), takeUntil with destroy$, or takeUntilDestroyed().
Observable: cold (each subscriber gets own execution), unicast. Subject: hot, multicast, no initial value, doesn't replay. BehaviorSubject: Subject that stores current value, emits it to new subscribers immediately. ReplaySubject: replays N last values. AsyncSubject: emits only last value on completion. Use BehaviorSubject for state that components need current value of immediately on subscription.
ReactiveFormsModule: FormControl (single control), FormGroup (group of controls), FormArray (dynamic array). Create in component class with FormBuilder. Bind template with [formGroup] and formControlName. Benefits: testable (no DOM needed), more control, complex validation. Access: form.get("field").value, form.valid, form.errors. Use Validators for sync, async validators for server-side checks.
RouterModule.forRoot() for root routes, forChild() for feature modules. Lazy loading: loadComponent (standalone) or loadChildren (module) splits bundle per route. Guards: CanActivate (auth check), CanDeactivate (unsaved changes), Resolve (prefetch data). Route params: ActivatedRoute.params Observable. RouterLink for navigation, Router.navigate() for programmatic. Use preloadingStrategy for faster subsequent navigation.
Signals (Angular 16+) are reactive primitives for fine-grained reactivity. signal() creates writable signal. computed() creates derived signal (like computed property, auto-tracks dependencies). effect() runs side effects when signals change. Signals integrate with change detection: OnPush components update automatically when signal changes. More predictable than Zone.js-based change detection. Angular 17+ makes signals the preferred reactive pattern.
Use HttpClient (import HttpClientModule). Methods return Observables. Use pipe(catchError()) for error handling, tap() for side effects, map() to transform response. Interceptors (HTTP_INTERCEPTORS): modify requests/responses globally (add auth headers, handle 401, loading spinners). Retry with retry() or retryWhen(). HttpContext for passing metadata to interceptors. Always type responses with generics.
Pipes transform template values: {{ value | date:"MM/dd/yyyy" }}. Built-in: date, currency, async (auto-subscribes Observable/Promise), json, uppercase, lowercase, decimal, percent, slice. Create custom: @Pipe({name: "myPipe", pure: true}) class. Pure pipes recalculate only when input reference changes. Impure pipes check on every change detection cycle — avoid if expensive. Standalone pipes with standalone: true.
The async pipe subscribes to Observable/Promise in template and automatically unsubscribes on component destroy. Benefits: no manual subscribe/unsubscribe, no memory leaks, triggers change detection for OnPush. Usage: {{ data$ | async }}. Combine with *ngIf as: *ngIf="data$ | async as data". Works with any Observable stream. Preferred over manual subscriptions in ngOnInit.
Zone.js patches async browser APIs (setTimeout, Promise, events) to notify Angular when async operations complete, triggering change detection. This enables Angular's "magic" automatic updates. Drawback: performance overhead, detects all async even unrelated to Angular. Zoneless Angular (experimental in 17+): manual change detection with signals, better performance. Use NgZone.runOutsideAngular() for non-Angular async to avoid unnecessary CD.
NgModule (traditional): declares components/pipes/directives, imports other modules, provides services. Requires declaring everything before use. Standalone components (Angular 14+, default in 17+): self-contained, import dependencies directly in @Component. No NgModule needed. Benefits: simpler mental model, better tree-shaking, easier lazy loading. Migration: standalone: true + import what was in the module.
Options: (1) @Input/@Output for parent-child, (2) Shared service with BehaviorSubject (service as store), (3) Angular Signals for reactive state, (4) NgRx (Redux pattern — for large apps), (5) Component Store (NgRx component-level). Avoid sharing state via component references. Service + BehaviorSubject is the standard for medium apps. NgRx for complex state with many interactions and time-travel debugging needs.
Practice with interactive quizzes and get instant feedback.
Start Free Practice