Angular is a TypeScript-based front-end web application framework maintained by Google. These questions cover core concepts including components, directives, services, RxJS, change detection, routing, forms, and performance optimization — spanning beginner to advanced levels.
Angular (v2+) is a complete rewrite of AngularJS, built with TypeScript and a component-based architecture. AngularJS used a scope/controller MVC pattern with two-way data binding via dirty checking, while Angular uses a hierarchical component tree, zone.js for change detection, and a dependency injection system built for modern JavaScript.
A component is the fundamental building block of an Angular application, consisting of a TypeScript class decorated with @Component, an HTML template, and optional CSS styles. Each component controls a portion of the UI and communicates with others via @Input and @Output decorators.
An NgModule is a class decorated with @NgModule that groups components, directives, pipes, and services for compilation and dependency injection. Standalone components (introduced in Angular 14) use standalone: true and declare their own imports directly, eliminating the need for NgModules for simpler applications.
Directives are classes that add behavior to DOM elements. The three types are: Component directives (directives with templates), Structural directives that modify the DOM layout (e.g., *ngIf, *ngFor), and Attribute directives that change the appearance or behavior of an element (e.g., ngClass, ngStyle).
DI is a design pattern where Angular's injector provides instances of services to components and other services rather than having them create dependencies themselves. Services are registered via providers in a module, component, or with providedIn: 'root' for application-wide singleton scope.
Template-driven forms rely on directives in the template (ngModel) and are simpler but less scalable. Reactive forms are defined programmatically using FormGroup and FormControl in the component class, offering more control, easier unit testing, and better support for complex validation scenarios.
Data binding synchronizes data between the component class and the template. The four types are: Interpolation ({{ value }}), Property binding ([property]="value"), Event binding ((event)="handler()"), and Two-way binding ([(ngModel)]="value") which combines property and event binding.
The lifecycle starts with constructor, followed by hooks fired by Angular: ngOnChanges (on @Input changes), ngOnInit (after first change detection), ngDoCheck, ngAfterContentInit, ngAfterContentChecked, ngAfterViewInit, ngAfterViewChecked, and ngOnDestroy (cleanup before destruction). ngOnInit and ngOnDestroy are the most commonly used.
Change detection is the mechanism Angular uses to synchronize the component tree with the data model, triggered by zone.js after async events. With ChangeDetectionStrategy.OnPush, Angular only checks a component when its @Input references change, an event originates within it, or an async pipe emits — significantly improving performance by reducing unnecessary checks.
RxJS is a library for reactive programming using Observables to handle asynchronous data streams. Angular uses it extensively — HttpClient returns Observables, the Router exposes navigation events as Observables, and the async pipe in templates subscribes and auto-unsubscribes from Observables automatically.
Subject is a multicast Observable that emits to current subscribers only. BehaviorSubject requires an initial value and emits the latest value to any new subscriber immediately upon subscription. ReplaySubject buffers a specified number of past emissions and replays them to new subscribers.
The Angular Router maps URL paths to components using a RouterModule configuration with a Routes array; router-outlet acts as the placeholder where matched components are rendered. Lazy loading defers loading of feature modules until their route is navigated to using loadChildren with a dynamic import, reducing initial bundle size.
The async pipe subscribes to an Observable or Promise in a template and automatically unsubscribes when the component is destroyed, preventing memory leaks. It also triggers change detection when a new value arrives, making it the preferred way to consume Observables in templates over manual subscription management.
@ViewChild queries elements or directives within the component's own template (view). @ContentChild queries elements projected into the component via ng-content (content). ViewChild is available after ngAfterViewInit; ContentChild is available after ngAfterContentInit.
Route guards are interfaces that control navigation. The main types are: CanActivate (prevents unauthorized access to a route), CanDeactivate (prevents leaving a route with unsaved changes), CanLoad (prevents lazy-loaded modules from loading), Resolve (pre-fetches data before route activation), and CanActivateChild (guards child routes).
switchMap cancels the previous inner Observable when a new source emission arrives (ideal for search/autocomplete). mergeMap runs all inner Observables concurrently. concatMap queues inner Observables and executes them sequentially. exhaustMap ignores new source emissions while an inner Observable is still active (ideal for login button clicks).
Key strategies include: using OnPush change detection, lazy loading feature modules, using trackBy with *ngFor, leveraging the async pipe, applying pure pipes instead of methods in templates, enabling Ahead-of-Time (AOT) compilation, using the Angular CLI's production build (--configuration production) for tree-shaking and minification, and virtualizing long lists with CDK Virtual Scroll.
zone.js patches browser async APIs (setTimeout, Promises, XHR) to notify Angular when to run change detection automatically. Zoneless Angular (stabilized in Angular 18) removes this dependency, relying instead on explicit signals or markForCheck() calls, resulting in faster startup, smaller bundles, and better interoperability with non-Angular code.
Signals (stable since Angular 17) are synchronous reactive primitives that hold a value and notify consumers automatically when it changes, tightly integrated into Angular's change detection. Observables are push-based lazy streams suited for async event sequences. Signals are simpler for local state and component reactivity, while Observables excel at complex async data pipelines.
HTTP interceptors implement the HttpInterceptor interface and are applied in a chain via the HTTP_INTERCEPTORS multi-provider token; each intercepts the request or response in order. Common use cases include attaching authentication tokens to outgoing requests, logging, global error handling, showing loading spinners, and response caching.
© RM Full Stack & AI Engineer · All interview questions · Roadmaps · Open the app