skip to content

Angular

2 roadmaps495 questionsupdated

Angular's own APIs: standalone components, templates, signals, change detection, DI, router, forms, HttpClient and SSR. Interviewers test whether you work inside the framework's conventions.

on this pageshow

guide

overview

~1 min

Angular is a TypeScript framework from Google that ships most of what a large web application needs in one package: components and a compiled template language, hierarchical dependency injection, a router, forms, an HTTP client, server rendering and a test toolkit. Interviewers use it to check whether you work with the framework's conventions or against them. A strong Angular answer names the API, the injector or view it runs in, and when Angular will next look at the result. The hub splits along how an application is built. [Component authoring](/topics/fe-angular-components-templates), the [template language](/topics/fe-angular-templates) and [directives and pipes](/topics/fe-angular-directives-pipes) cover what a view declares. [Signals](/topics/fe-angular-signals), [change detection](/topics/fe-angular-change-detection) and [RxJS usage patterns](/topics/fe-angular-rxjs-signals) cover how state changes reach the screen. [Hierarchical dependency injection](/topics/fe-angular-dependency-injection) and [bootstrapping and modules](/topics/fe-angular-app-structure) explain where services and configuration come from. The application layer is the [router](/topics/fe-angular-modules-routing), [forms](/topics/fe-angular-forms) and the [HTTP client](/topics/fe-angular-http). Delivery and quality sit on top: [SSR and prerendering](/topics/fe-angular-ssr), [load and render speed](/topics/fe-angular-performance), [security defences](/topics/fe-angular-security), [localization](/topics/fe-angular-i18n), [animations](/topics/fe-angular-animations), [unit testing](/topics/fe-angular-testing), [compilation and tooling](/topics/fe-angular-compiler) and [upgrades and legacy code](/topics/fe-angular-upgrades). Junior rounds ask how a component receives data, how a template binds it and where a service instance comes from. Senior rounds turn into trade-offs and diagnoses: why a view did not update, why a request fired twice, why hydration broke, what a multi-major upgrade will cost. Angular has changed fast, so many questions also test whether you know the current idiom and can still read the older one. Start with components and templates, then signals and dependency injection. Change detection only makes sense once those are clear, and the router, forms, HTTP and SSR all build on the four.

primer

### A component is a class with a declared contract Every Angular view is a component: a TypeScript class plus metadata naming its selector, template, styles and what that template may use. Its public surface is its inputs, outputs and projected content, and interviewers read your answers for whether you respect that boundary — data in through inputs, events out through outputs, never reaching into a child's internals. Current code declares that surface with functions (`input()`, `output()`, `model()`, `viewChild()`); older code does the same with decorators, and both must be readable. ### Standalone is the default; NgModules are legacy you still meet New applications start from `bootstrapApplication` with a list of providers, and each component imports what its own template uses. NgModules grouped declarations and gave them a shared compilation scope; plenty of production code still relies on them. Expect to explain both models and how they interoperate during a migration. ### Dependency injection is a tree, not a global registry An injected value comes from the nearest injector that has a provider for its token. Element injectors follow the component tree; environment injectors cover the application root and lazily loaded routes. Where you register a provider therefore decides how many instances exist and how long they live — the answer behind most "why do I have two copies of this service" questions. `inject()` works only inside an injection context, which is why its placement matters. ### Signals hold state; RxJS models events over time Signals are synchronous values that know who reads them. `computed()` derives values lazily and caches them, `effect()` pushes changes out to non-signal code, and `resource()` brings async loading into the same graph. RxJS remains the model for streams — HTTP calls, router events, sockets — and the interop bridges convert between the two. A good answer picks the right one for the job and says where the conversion happens. ### Change detection is scheduled work over a tree of views Angular refreshes a view by re-evaluating its bindings. The questions are *when* a pass runs and *which* views it visits. With zone.js, a pass is scheduled after async tasks settle; zoneless applications are notified by signals, template events and explicit marking instead. OnPush components are skipped unless something marked them dirty. Most "the screen did not update" and "the app feels slow" answers come down to this. ### Templates are compiled, typed code The compiler turns templates into instructions at build time and can type-check every binding against the component. Built-in control flow (`@if`, `@for`, `@switch`, `@defer`) is part of that language, not a directive you import. Treat a template expression as code that executes each time Angular checks its view, because that is exactly what happens. ### Bundles are drawn by routes and deferred views Lazy routes and `@defer` blocks are Angular's two ways to keep code out of the initial download. Both are declared where the feature is used, so performance questions often start with how the route tree and templates are organised rather than with micro-optimisation. ### The same code may run on the server first With SSR or prerendering, components execute in Node before the browser hydrates the result. Code that assumes a browser, or renders differently on each side, breaks hydration. Knowing which lifecycle and render hooks run where is now baseline knowledge for senior roles.

Standalone component
A component that imports the components, directives and pipes its template uses itself, instead of relying on an NgModule's declarations. The default for new Angular code.
NgModule
A class decorated with @NgModule that groups declarations, imports, exports and providers and defines a compilation scope. The older way to organise an Angular application.
Injection token
The key the injector uses to find a provider: a class, or an InjectionToken instance for values without a class, such as configuration objects.
Provider
A registration that tells an injector how to produce the value for a token: by class, fixed value, factory function or alias.
Injection context
The places where inject() is allowed: constructors, field initializers, factory functions and a few framework callbacks, or code run through runInInjectionContext.
Environment injector
An injector not tied to an element: the root and platform injectors, plus those created for routes that declare providers or lazily load child routes.
Element injector
An injector created for a component or directive that declares providers, visible to that element and its view subtree.
Signal
A reactive value read by calling it. Angular tracks which computations and templates read a signal and notifies them when it changes.
computed()
A read-only signal derived from other signals. It recalculates lazily, only when read after one of its dependencies changed, and caches the result.
effect()
A callback that re-runs when signals it read change, used to push signal state into code outside the signal graph, such as storage or logging.
Change detection
The process of re-evaluating a view's template bindings and updating the DOM where values changed, run over the component tree.
OnPush
A change detection strategy under which a component's view is refreshed only after it has been marked dirty; the default since Angular 22.
zone.js
A library that patches browser async APIs so Angular learns when tasks finish and can schedule change detection. Zoneless applications do without it.
Control flow blocks
The built-in @if, @for, @switch and @defer template syntax, compiled by Angular and replacing the older structural directives such as *ngIf and *ngFor.
Deferrable view
A @defer block whose content and dependencies are split into a separate chunk, loaded when a trigger fires, with optional placeholder, loading and error blocks.
Functional guard
A plain function in a route's configuration that decides whether navigation may proceed, returning a boolean, a redirect or an async version of either.
Hydration
Reusing server-rendered DOM in the browser and attaching Angular's listeners and state to it, instead of throwing the markup away and rendering again.
Ahead-of-time compilation
Compiling templates and decorators into JavaScript during the build, so the browser receives no template compiler and template errors fail the build.

Follow an application from start to screen. `bootstrapApplication` builds the root environment injector from the providers you list — router, HTTP features, hydration, error handling — and renders the root component. The router matches the URL against its route tree, runs guards and resolvers, may fetch a lazy chunk (a route with its own providers also gets its own environment injector), and places the matched component into an outlet. Each component gets its dependencies from the injector tree, receives inputs from its parent, and renders a template that the compiler has already turned into code. State flows through that tree in one direction. Services hold shared state, often as signals; components derive what they show with `computed()`; templates read those signals, which registers the view as a consumer. When a signal changes, Angular marks the views that read it for refresh and schedules a pass; OnPush views nobody marked are skipped. Streams from HttpClient, the router or a socket enter through `toSignal()`, the async pipe or a subscription that ends with the component. Several small ideas meet in one ordinary component: ```typescript @Component({ selector: 'app-order-list', imports: [OrderLine], template: ` @for (line of visible(); track line.id) { <app-order-line [line]="line" (removed)="store.remove($event)" /> } `, }) export class OrderList { protected store = inject(OrderStore); query = input(''); visible = computed(() => this.store.lines().filter(l => l.sku.includes(this.query()))); } ``` The component imports its own child, gets `OrderStore` from whichever injector provides it, and derives `visible` from a service signal and an input signal. When either changes, only this view needs refreshing, and `track` lets the loop keep existing rows instead of rebuilding them. The rest of the hub attaches to this path: - **Forms** build a model of controls beside the template; custom inputs join it through a value accessor. - **SSR** runs the same bootstrap on the server; hydration and the transfer cache connect the two runs. - **Performance** work mostly moves code behind lazy routes and `@defer`, and keeps template bindings cheap. - **Testing** rebuilds a small injector and view with TestBed so a spec exercises the same wiring.

  1. Component Authoring →

    Where every Angular answer starts: how a component declares its selector, inputs, outputs, projection slots and lifecycle.

  2. Template Language →

    The binding syntax and control flow blocks that every later section writes in, from interpolation to @for with track.

  3. Signals →

    The reactive primitives current Angular code is built on: writable and derived state, effects and async resources.

  4. Hierarchical Dependency Injection →

    Where every service instance comes from, and why the place you provide it decides how many exist and how long they live.

  5. Change Detection →

    Ties signals, templates and events together: when views refresh, what OnPush skips and why screens go stale.

  6. SPA Router →

    The first application-level feature: route definitions, guards and lazy chunks that shape both navigation and bundle size.

  • Putting input-dependent setup in the constructor: inputs are not bound yet, so the code sees defaults; use ngOnInit or derive the value from signal inputs.

  • Describing change detection as checking the whole tree after every event: that is the older Eager-with-zone.js picture, and components have defaulted to OnPush since Angular 22.

  • Calling a method or getter from a template to derive a value; it re-runs whenever the view is checked, where computed() or a pure pipe would cache it.

  • Subscribing inside a component without a teardown plan — prefer the async pipe, toSignal() or takeUntilDestroyed() so the subscription ends with the view.

  • Using effect() to copy one signal into another; derived state belongs in computed() or linkedSignal(), and effects are for leaving the signal graph.

  • Listing a service in a component's providers and expecting a singleton; each component instance gets its own copy, visible only to its subtree.

  • Silencing ExpressionChangedAfterItHasBeenCheckedError with a timeout or an extra detectChanges() instead of fixing the data flow that changed a value mid-pass.

  • Tracking a dynamic @for list by $index: rows are matched by position, so DOM state such as focus or typed text stays put while the items move.

  • Touching window, localStorage or the DOM directly in code that also runs during SSR; see Browser-Only Code Paths.

  • Reaching for a bypassSecurityTrust method to make a warning go away with user-supplied content, which switches off the sanitization protecting that binding.

This guide assumes **Angular 22**, the release line the questions below are written against. Angular has moved quickly, and interviewers still probe the transitions because most production codebases sit somewhere between eras: - **Standalone components** arrived in v14 and became stable in v15; they later became the default, and new projects no longer generate NgModules. - **Signals** first shipped in v16. Signal-based inputs, outputs, model inputs and queries followed in later releases, then `linkedSignal()` and `resource()` for derived and async state. - **v17** introduced the built-in control flow blocks and `@defer`. The structural directives `*ngIf`, `*ngFor` and `*ngSwitch` have been deprecated since v20. - **v21** made `HttpClient` available from the root injector without calling `provideHttpClient()`. - **v22** made OnPush the default change detection strategy, turned on strict template type-checking by default, and moved Angular to roughly one major release a year. Other shifts run through several releases rather than one: zoneless change detection, the native `animate.enter` and `animate.leave` hooks replacing the deprecated `@angular/animations` package, incremental hydration, signal-based forms and the unit-test runner choice. When an answer depends on the version — default strategy, how a component is bootstrapped, which forms model to reach for — say which version you are describing.

Angular is usually placed against **React** and **Vue**. The separating trade-off is scope: Angular ships routing, forms, HTTP, dependency injection, i18n, SSR and a test toolkit as one versioned framework with one CLI, while React is a view library around which teams choose their own pieces, and Vue sits in between with official but optional companions. Angular's bet is consistency across large teams and long-lived codebases; the cost is more framework concepts to learn up front and upgrades that move the whole stack at once. A defensible answer ties the choice to team size, codebase lifetime and how much the organisation wants to standardise. Around the core you are expected to know the neighbours. **TypeScript** is required, not optional. **RxJS** is a peer dependency that HttpClient, the router and reactive forms expose, even as signals take over component state. The **Angular CLI** drives builds, code generation and the migration schematics used in upgrades. **Angular Material** and the **CDK** provide components and behaviour primitives, and the CDK's test harnesses appear in [Harness-Based Queries](/topics/fe-angular-testing-harnesses). For shared state, many teams add a store library such as NgRx; others keep state in signal-based services, and interviewers ask you to justify either. **AngularJS** is a different, earlier framework — see [AngularJS Differences](/topics/fe-angular-upgrades-angularjs).

explore

report an issue with this guide →

questions

495 · 19 sections

In Angular, how do you declare component inputs with input() and input.required(), and how do they differ from the @Input decorator?

level: juniorimportance: must knowfreq 76%
basics
~10 s

input(default) and input.required<T>() declare inputs as read-only InputSignal fields you read by calling them, and a missing required binding is a compile error. @Input() marks a plain, reassignable property and remains fully supported.

open as a page

In an Angular component, what work belongs in the constructor and what belongs in ngOnInit, and why?

level: juniorimportance: must knowfreq 82%
basics
~20 s

The constructor runs when Angular creates the instance, before any parent bindings are applied, so it should only inject dependencies and register setup. ngOnInit runs once after the first input values are set, so input-dependent initialisation belongs there.

open as a page

In an Angular standalone component, what does the @Component imports array do, and what happens if a used child component is missing from it?

level: juniorimportance: must knowfreq 72%
basics
~10 s

The imports array lists the components, directives, pipes and NgModules a standalone component's template may use. A missing element-selector child fails the build with NG8001; a missing attribute-selector child is silently never created.

open as a page

In an Angular component, what does model() declare, and what can a parent template bind to it?

level: juniorimportance: must knowfreq 62%
basics
~20 s

model() declares a writable signal input: the parent can bind a value in, the child can set() or update() it, and Angular adds a <name>Change output so a [( )] binding to a signal or plain property stays in sync.

open as a page

In Angular, how does a child component emit a custom event with output() or @Output and EventEmitter, and how does the parent read its payload?

level: juniorimportance: must knowfreq 74%
basics
~10 s

The child declares rated = output<number>() or @Output() rated = new EventEmitter<number>() and calls rated.emit(value). The parent binds (rated)="save($event)", where $event is exactly the emitted value, not a DOM event.

open as a page

In current Angular templates, how do you write an if / else-if / else, and how does it replace *ngIf with an else template?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Use the built-in @if (cond) { } @else if (other) { } @else { } blocks. They replace *ngIf="cond; else tpl" plus an <ng-template #tpl>, need no import, and *ngIf has been deprecated since v20.

open as a page

In an Angular template, how does an (event)="statement" binding work, and what does the $event variable hold?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Parentheses around an event name make Angular listen for that event and run the quoted template statement each time it fires. $event is the native DOM event object, or the value a component output emitted.

open as a page

In an Angular template, what does {{ }} interpolation evaluate its expression against, and what text does it render for null, undefined or an object?

level: juniorimportance: must knowfreq 58%
basics
~20 s

Interpolation evaluates its expression against the component instance, with this implied, plus any template variables in scope, converts the result to a string and writes it as text. null and undefined render as an empty string; an object renders through String().

open as a page

In Angular's @for block, why is the track expression mandatory, and what should you usually pass to it?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Angular's @for requires track so the runtime can match each item to its existing row view by key. Track a stable unique field like item.id, use $index only for static lists, and the item itself only as a last resort.

open as a page

In an Angular template, what is the difference between a property binding such as [value] and an attribute binding such as [attr.colspan]?

level: juniorimportance: must knowfreq 68%
basics
~20 s

[value] writes the element's DOM property, or a matching component or directive input, and is checked at compile time. [attr.colspan] calls setAttribute with the stringified value and removes the attribute for null or undefined; use it when no matching property exists.

open as a page

In Angular, what is an attribute directive, and how would you build and apply an appHighlight directive that highlights an element on hover?

level: juniorimportance: must knowfreq 70%
basics
~20 s

An Angular attribute directive is a class decorated with @Directive and an attribute selector such as [appHighlight]; it adds behaviour to an existing element or component. Import it into the using component, react to host events and set styles via host bindings or ElementRef.

open as a page

In an Angular template, how do you format an invoice's amount, issue date and quantity with built-in pipes, including arguments and chaining?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Apply the currency, date and number pipes with |, e.g. amount | currency:'EUR', issuedOn | date:'longDate', qty | number:'1.0-0'. Arguments follow colons in order, and chained pipes run left to right.

open as a page

How do you write a custom Angular pipe with @Pipe and PipeTransform, give it an extra argument, and use it in a standalone component?

level: juniorimportance: must knowfreq 62%
basics
~10 s

Decorate a class with @Pipe({ name: 'truncate' }), implement PipeTransform's transform(value, ...args), and add the class to the standalone component's imports. Extra transform parameters become colon-separated arguments, as in text | truncate: 40.

open as a page

In Angular, what is the difference between <ng-template> and <ng-container>, and what does each leave in the rendered DOM?

level: juniorimportance: must knowfreq 68%
basics
~20 s

<ng-template> declares a fragment that Angular compiles but renders only when an outlet or code stamps it; <ng-container> renders its children immediately without adding a wrapper element. Neither becomes an HTML element itself; each is represented by a comment node.

open as a page

What does the asterisk prefix on an Angular structural directive, as in `<li *ngIf="user as u">`, desugar to at compile time?

level: juniorimportance: must knowfreq 60%
basics
~10 s

The Angular compiler wraps the element in an ng-template that carries only the structural directive and its microsyntax bindings; the directive then renders that template, or not, through TemplateRef and ViewContainerRef.

open as a page

In Angular, what does effect() do, where must you call it, and when does its callback run for the first time?

level: juniorimportance: must knowfreq 70%
basics
~20 s

effect() runs a side-effect callback that re-runs whenever a signal it read last time changes. It must be created in an injection context or given an injector, and it first runs asynchronously during the next change detection, not when created.

open as a page

In Angular, what does linkedSignal() give you that neither a plain signal() nor a computed() does?

level: juniorimportance: must knowfreq 50%
basics
~20 s

linkedSignal() is a writable signal whose value is initialised and reset by a computation. You can set() it like a signal(), but whenever the signals its computation reads change, it recomputes and replaces whatever was set.

open as a page

In Angular, how does resource() turn a selected user id signal into loaded order history, and what do its params and loader options do?

level: juniorimportance: must knowfreq 52%
basics
~20 s

resource() pairs a reactive params function with an async loader: whenever the signals read in params produce a new value, Angular calls the loader with it and exposes the result through signals such as value(), status() and isLoading().

open as a page

In an Angular component, why derive a cart total with computed() instead of a getter or a method called from the template?

level: juniorimportance: must knowfreq 72%
basics
~20 s

computed() is lazy and memoized: its function runs on first read and its result is cached until a signal it read changes. A template getter or method reruns on every check of that view, and nothing caches its result.

open as a page

In Angular, how do you create a writable signal with signal(), read its value, and change it with set() versus update()?

level: juniorimportance: must knowfreq 78%
basics
~20 s

signal(initialValue) returns a WritableSignal: a getter function you call, such as qty(), to read the value. set(value) replaces the value outright, while update(fn) computes the next value from the current one and must return it.

open as a page

In Angular, what does the async pipe do over a component's lifetime when its template binds `notifications$ | async`?

level: juniorimportance: must knowfreq 80%
basics
~20 s

Angular's async pipe subscribes to the Observable or Promise when the binding is first evaluated, returns its latest value, calls markForCheck on each asynchronous emission, swaps subscriptions if the reference changes, and unsubscribes when the view is destroyed.

open as a page

In an Angular observable data service, why keep the BehaviorSubject private and expose state through asObservable() instead?

level: juniorimportance: must knowfreq 66%
basics
~20 s

A private BehaviorSubject means only the service's own methods can emit new state, so every change goes through one path; asObservable() gives consumers an Observable backed by the subject that has no next(), error() or complete() to call.

open as a page

In an Angular component, how does `toSignal()` expose a WebSocket price feed to the template, and when does it subscribe and unsubscribe?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Angular's toSignal() subscribes to the Observable as soon as it is called, stores each emission in a read-only signal the template reads with (), and unsubscribes when the calling component's or service's DestroyRef fires.

open as a page

In Angular, why does calling HttpClient.get() without subscribing send no request, and why does subscribing to the result twice send two?

level: juniorimportance: must knowfreq 62%
basics
~20 s

HttpClient methods return cold Observables: the call only describes the request, and each subscription runs the interceptor chain and backend again, sending a new request. With the default observe: 'body' each run emits one body and completes.

open as a page

In Angular, how does `takeUntilDestroyed()` from `@angular/core/rxjs-interop` end a subscription, and where can you call it without an argument?

level: juniorimportance: must knowfreq 75%
basics
~20 s

Angular's takeUntilDestroyed() pipes the source through takeUntil with a notifier fired by a DestroyRef's onDestroy callback, so the stream completes when the component, directive or injector is destroyed; without an argument it must run in an injection context.

open as a page

What does Angular's ExpressionChangedAfterItHasBeenCheckedError (NG0100) mean, and why do you only ever see it in development mode?

level: juniorimportance: must knowfreq 72%
basics
~20 s

NG0100 means a template binding produced a different value in Angular's dev-mode verification pass than in the change detection pass just before it. The extra pass runs only in development builds, so production shows the stale value silently instead of throwing.

open as a page

In Angular, what is the difference between ChangeDetectorRef.markForCheck() and ChangeDetectorRef.detectChanges()?

level: juniorimportance: must knowfreq 72%
basics
~10 s

markForCheck() only marks the view and its ancestors dirty and notifies the scheduler, so the next change-detection pass refreshes them; detectChanges() synchronously checks this view and its descendants right now, without touching ancestors.

open as a page

In Angular 22, what is the difference between ChangeDetectionStrategy.OnPush and ChangeDetectionStrategy.Eager, and which does a component get by default?

level: juniorimportance: must knowfreq 82%
basics
~20 s

An Eager component is refreshed every time a change detection pass reaches it; an OnPush component is refreshed only when its view has been marked dirty. Since Angular 22, a component that omits changeDetection is OnPush.

open as a page

In a zone-based Angular app, how does zone.js tell Angular to run change detection after a setTimeout callback or a click handler?

level: juniorimportance: must knowfreq 68%
basics
~10 s

zone.js patches async browser APIs such as timers, promises and event listeners, so NgZone sees each callback run in the Angular zone; when its microtask queue drains, NgZone emits onMicrotaskEmpty and Angular calls ApplicationRef.tick().

open as a page

What does it mean that an Angular v21+ application is zoneless by default, and what does dropping zone.js gain you?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Since v21, Angular schedules change detection from its own notifications (template-read signal writes, markForCheck, bound listeners, setInput) instead of zone.js patching browser APIs. Dropping zone.js means fewer needless checks, a smaller bundle, faster startup and readable stack traces.

open as a page

In Angular, what is the difference between injecting with inject() and injecting through constructor parameters, and which does the style guide recommend?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Both resolve dependencies from the same injector in the same way. inject() is called in a field initializer or constructor, giving better type inference, no super() forwarding and use in plain functions; Angular's style guide prefers it.

open as a page

In Angular, what do the provider recipes useClass, useValue, useFactory and useExisting each tell the injector to return?

level: juniorimportance: must knowfreq 72%
basics
~20 s

An Angular provider pairs a token with a recipe: useClass instantiates a class, useValue returns a fixed value untouched, useFactory returns what a function builds, and useExisting aliases another token. A bare class is shorthand for useClass of itself.

open as a page

In Angular, how does a service declared with providedIn: 'root' differ from one listed in a component's providers array in instance count and lifetime?

level: juniorimportance: must knowfreq 76%
basics
~20 s

providedIn: 'root' gives one application-wide instance, created lazily on first injection and kept until the app is destroyed. A component's providers array creates a separate instance for each component instance, visible to its subtree and destroyed with it.

open as a page

In Angular, why can't a TypeScript interface serve as a DI token, and how does an InjectionToken solve that for an API_BASE_URL string?

level: juniorimportance: must knowfreq 62%
basics
~20 s

TypeScript interfaces are erased at compile time, so there is nothing at runtime for the injector to use as a key. An InjectionToken<T> is a real object that serves as that key, and its type parameter makes inject() return T.

open as a page

In Angular, where does an injection context exist, and why does calling inject() inside ngOnInit throw NG0203?

level: middleimportance: must knowfreq 60%
basics
~20 s

An injection context exists while Angular creates a DI-managed instance (field initializers, constructor), inside provider and InjectionToken factories, and in functions the framework runs in context, such as guards. ngOnInit runs after construction, when no context is active, so inject() throws NG0203.

open as a page

In Angular, what does the default ErrorHandler do with an uncaught error, and how do you replace it with your own class?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Angular's default ErrorHandler only logs the error with console.error. To replace it, write a class with a handleError(error) method and register { provide: ErrorHandler, useClass: MyHandler } in the application's providers.

open as a page

In Angular, what does provideAppInitializer do, and why did it replace the APP_INITIALIZER token?

level: juniorimportance: must knowfreq 52%
basics
~10 s

provideAppInitializer registers a function Angular runs during bootstrap, before the root component is created; if it returns a Promise or Observable, startup waits for it. It replaced the APP_INITIALIZER multi-provider token, deprecated since v19.

open as a page

In Angular, what do the declarations, imports, exports, providers and bootstrap fields of an @NgModule each do?

level: juniorimportance: must knowfreq 70%
basics
~10 s

declarations lists the non-standalone components, directives and pipes a module owns; imports brings in what its templates use; exports shares declarables with importers; providers registers services; bootstrap names the root component bootstrapModule renders.

open as a page

In Angular, how does bootstrapApplication start a standalone app, and what belongs in the ApplicationConfig passed to it?

level: juniorimportance: must knowfreq 72%
basics
~10 s

bootstrapApplication(App, appConfig) in main.ts renders a standalone root component and builds the root injector from ApplicationConfig, whose only field is a providers array of plain providers and provideX() functions. It returns a Promise<ApplicationRef>.

open as a page

In Angular, which errors reach the ErrorHandler automatically, and which ones never get there?

level: middleimportance: must knowfreq 50%
basics
~20 s

Errors thrown in code Angular runs for you — constructors, lifecycle hooks, template bindings, template event listeners, async pipe sources, bootstrap — reach ErrorHandler. Errors you catch, errors exposed as state like resource().error, and free async errors without global listeners do not.

open as a page

In Angular, how would you define routes for a blog with /posts, /posts/:slug and a 404 page, and does their order matter?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Register a Routes array with provideRouter: 'posts', 'posts/:slug' and a final '**' route for the 404 page. Order matters: the router uses the first route that matches, so the wildcard goes last.

open as a page

In an Angular app, how do you drive a top-of-page loading bar from the router, and why does a NavigationStart/NavigationEnd pair leave it stuck?

level: juniorimportance: must knowfreq 58%
basics
~10 s

Show the bar while Router.currentNavigation() is non-null, or start it on NavigationStart and stop it on NavigationEnd, NavigationCancel or NavigationError. Stopping only on NavigationEnd leaves it running after cancelled or failed navigations.

open as a page

In Angular, how do you write a functional canActivate guard that lets only admins into an /admin route and redirects everyone else?

level: juniorimportance: must knowfreq 80%
basics
~10 s

Write a CanActivateFn that injects the auth service, returns true for admins and returns a UrlTree (router.createUrlTree(['/login'])) or a RedirectCommand for everyone else, then list it in the route's canActivate array.

open as a page

In Angular, how do you lazy-load a route with loadComponent versus loadChildren, and what does a default export let you omit?

level: juniorimportance: must knowfreq 70%
basics
~10 s

loadComponent takes a function returning import() of one standalone component; loadChildren returns a module whose export is a Routes array. When the file uses export default, the .then(m => m.X) step can be dropped.

open as a page

In Angular reactive forms, how do FormControl, FormGroup and FormArray fit together, and how does a template bind to them?

level: juniorimportance: must knowfreq 80%
basics
~20 s

FormControl holds one value, FormGroup holds named child controls, and FormArray holds an indexed list; all extend AbstractControl and nest into a tree built in the class. The template binds it with [formGroup], formControlName, formGroupName and formArrayName from ReactiveFormsModule.

open as a page

In Angular Signal Forms, how do form(), a schema function and the [formField] directive work together in a registration form?

level: juniorimportance: must knowfreq 48%
basics
~20 s

The data lives in a writable signal; form(model, schema) returns a FieldTree mirroring it; the schema runs once, binding rules like required() to paths; [formField] two-way binds an input to a field, whose state you read by calling it.

open as a page

In Angular, how do template-driven forms differ from reactive forms, and when is a template-driven form the right choice?

level: juniorimportance: must knowfreq 75%
basics
~20 s

Template-driven forms let ngModel and NgForm directives build the FormControl tree implicitly from the markup, bound to plain component properties; reactive forms build that tree explicitly in the class. Template-driven fits small, static forms such as a newsletter sign-up.

open as a page

In Angular's typed reactive forms, why is new FormControl('') inferred as FormControl<string | null>, and how do you remove the null?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Calling reset() on a plain FormControl sets its value to null, so Angular adds null to the inferred type. Passing {nonNullable: true} makes reset() return to the initial value instead, and the type becomes FormControl<string>.

open as a page

In Angular reactive forms, how do you attach built-in validators such as Validators.required and Validators.minLength, and how do you read the errors they produce?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Angular's built-in validators are functions passed to a control, either as the second argument or in the validators option. Each failing validator adds a key to control.errors, which is null when the control is valid.

open as a page

In Angular, how do you write an HttpInterceptorFn that attaches a bearer token to API requests, and why must it clone the request?

level: juniorimportance: must knowfreq 72%
basics
~20 s

An HttpInterceptorFn receives the outgoing HttpRequest and a next function. Because HttpRequest is immutable, it builds a copy with req.clone({ setHeaders: { Authorization: 'Bearer ...' } }) and returns next(copy), reading the token through inject() and skipping URLs outside its own API.

open as a page

With Angular's HttpClient, why does a WeatherService method returning http.get<Forecast>() send no request, and when does it send two?

level: juniorimportance: must knowfreq 74%
basics
~20 s

HttpClient methods return cold Observables: building one sends nothing, every subscription sends its own request, and unsubscribing before the response arrives aborts it. A method that only returns the Observable stays silent until something subscribes.

open as a page

In Angular, when does httpResource() send a request for a reviews panel keyed by a productId signal, and what does it expose?

level: juniorimportance: must knowfreq 55%
basics
~20 s

httpResource() tracks the signals its request function reads and sends the request eagerly, then again whenever one of them changes, cancelling any pending request. Returning undefined keeps it idle. It exposes value, status, error, isLoading, headers and statusCode as signals.

open as a page

In a standalone Angular 22 app, how is HttpClient made available, and when do you still need provideHttpClient()?

level: juniorimportance: must knowfreq 66%
basics
~10 s

Since Angular 21, HttpClient is provided in root, so inject(HttpClient) works with no setup. provideHttpClient() in the application providers is still how you add features: withInterceptors, withInterceptorsFromDi, withXsrfConfiguration or withNoXsrfProtection, withXhr and withRequestsMadeViaParent.

open as a page

With Angular's HttpClient, how are a 404, a network failure and an unparseable 200 response each reported, and what does status 0 mean?

level: middleimportance: must knowfreq 62%
basics
~20 s

All three reach the error channel as an HttpErrorResponse. A 404 keeps status 404 and the error body in error; status 0 means no HTTP response reached the app (offline, CORS block, timeout); an unparseable 200 keeps status 200 and a parsing message.

open as a page

In Angular, what does provideClientHydration() change about how a server-rendered page starts in the browser, and where must it be provided?

level: juniorimportance: must knowfreq 60%
basics
~10 s

provideClientHydration() makes Angular reuse the server-rendered DOM instead of discarding it and rendering again. It must be in the server bootstrap as well as the client, or no hydration data is sent.

open as a page

Why does an Angular component that reads window.innerWidth in its constructor crash during server-side rendering, and what are the server-safe alternatives?

level: juniorimportance: must knowfreq 66%
basics
~20 s

During SSR the component's constructor runs in Node, where window, localStorage and navigator do not exist, so the read throws. Move browser work into afterNextRender, reach the document through the DOCUMENT token, or guard browser-only logic with isPlatformBrowser(PLATFORM_ID).

open as a page

In an Angular app using @angular/ssr, how do you mark a route for build-time prerendering, and what does the build produce for it?

level: juniorimportance: must knowfreq 52%
basics
~10 s

Give the route RenderMode.Prerender in the server routes passed to provideServerRendering(withRoutes(...)). At build time Angular renders it once and writes a static index.html for that path, which is served as-is to every visitor.

open as a page

In Angular's @angular/ssr, what do RenderMode.Server, RenderMode.Client and RenderMode.Prerender do, and where do you assign them?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Each ServerRoute passed to withRoutes() sets a renderMode: Server renders HTML on every request, Prerender renders it once at build time, and Client returns the unrendered shell so the browser renders the page.

open as a page

In an Angular SSR app, why don't HttpClient GET requests made during the server render run again in the browser?

level: juniorimportance: must knowfreq 58%
basics
~20 s

Angular's HTTP transfer cache records eligible HttpClient responses made during the server render, serializes them into the HTML, and replays them in the browser during hydration, so the same GET or HEAD request is not sent twice.

open as a page

In an Angular @defer block, what do the @placeholder, @loading and @error sub-blocks show, and are their dependencies deferred?

level: juniorimportance: must knowfreq 55%
basics
~20 s

In Angular, @placeholder shows before the @defer trigger fires, @loading replaces it while the deferred chunk downloads, and @error shows if that download fails. All three are optional, and their own dependencies are loaded eagerly.

open as a page

In Angular, which triggers can an @defer block use, and what happens when you write @defer with no trigger at all?

level: juniorimportance: must knowfreq 62%
basics
~10 s

An Angular @defer block loads its content when an on trigger fires (idle, viewport, interaction, hover, immediate or timer) or a when condition turns truthy. With no trigger written, it defaults to on idle.

open as a page

In Angular, what does NgOptimizedImage do when you replace an img's src with ngSrc, and why must you give width and height?

level: juniorimportance: must knowfreq 52%
basics
~20 s

Angular's NgOptimizedImage takes over an img tagged with ngSrc: it sets loading, fetchpriority and decoding, builds src and srcset through a loader, and runs dev checks. width and height are required, or fill, so the browser reserves space and avoids layout shift.

open as a page

In an Angular template, why is binding to a component method such as {{ getTotal() }} considered a performance risk?

level: juniorimportance: must knowfreq 72%
basics
~20 s

Angular re-evaluates every binding in a view each time it checks that view, so a template method runs on every check rather than only when its inputs change; a slow or per-row method multiplies that cost.

open as a page

In Angular, why can a component used inside a @defer block still end up in the initial bundle instead of a lazy chunk?

level: middleimportance: must knowfreq 48%
basics
~20 s

Angular defers a dependency only if it is standalone and nothing else in the same file references it as a value. A reference outside the block, a viewChild query, a non-standalone class or a barrel import keeps it eager.

open as a page

In Angular, what happens to a user-supplied string containing HTML when you render it with {{ }} interpolation versus binding it to [innerHTML]?

level: juniorimportance: must knowfreq 74%
basics
~20 s

Interpolation writes the string as text, so tags appear literally and nothing runs. [innerHTML] parses it as HTML, but Angular first sanitizes it in the HTML security context, dropping scripts and event-handler attributes and neutralizing javascript: URLs.

open as a page

In Angular, what does DomSanitizer.bypassSecurityTrustResourceUrl return, and when is calling one of the bypassSecurityTrust methods justified?

level: middleimportance: must knowfreq 57%
basics
~20 s

It returns a SafeResourceUrl: a wrapper around the unchanged string, branded for the resource URL context, that bindings unwrap without sanitizing. A bypass is justified only for a value you built from trusted parts that Angular would otherwise block.

open as a page

Why can an Angular app compiled ahead of time run under a CSP without 'unsafe-eval', while a JIT-compiled app cannot?

level: juniorimportance: should knowfreq 38%
basics
~20 s

AOT compiles templates into JavaScript at build time, so the browser only runs ordinary bundled code. The JIT compiler generates template code in the browser and evaluates it with eval or new Function, which a script-src without 'unsafe-eval' blocks.

open as a page

In an Angular app, how do you change the XSRF cookie and header names HttpClient uses, or turn its XSRF handling off, and when is each justified?

level: juniorimportance: should knowfreq 30%
basics
~20 s

Pass withXsrfConfiguration({cookieName, headerName}) to provideHttpClient to match your backend's names, or withNoXsrfProtection() to remove the interceptor. Rename when the backend or a shared domain needs it; disable only when another defence, such as header-sent bearer tokens, makes it unnecessary.

open as a page

In Angular, what does the LOCALE_ID token control, and how do it and the locale data get set for a German build?

level: juniorimportance: must knowfreq 55%
basics
~20 s

LOCALE_ID names the active locale; the date, number, currency and percent pipes and ICU plural rules read it together with that locale's CLDR data. A --localize build sets both per locale; otherwise you provide LOCALE_ID and register the data yourself.

open as a page

In Angular, how do you mark template text, an element attribute, and a string in component code for translation?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Template text gets the i18n attribute on its element, an attribute value gets i18n-<attribute> (for example i18n-title), and strings in TypeScript use the $localize tagged template literal. <ng-container i18n> marks text without adding an element.

open as a page

With the Angular CLI localize option, what does building en-US, de and ja variants produce, and how are those variants served?

level: middleimportance: must knowfreq 45%
basics
~20 s

The CLI compiles the app once, then inlines each locale's translations into a separate copy with its own directory, base href, html lang, LOCALE_ID and locale data. A server or Angular SSR redirects the root to the best-matching locale sub-path.

open as a page

In an Angular template, how do you use ICU plural and select expressions for a cart summary that varies by item count and shopper gender?

level: middleimportance: must knowfreq 48%
basics
~20 s

Inside i18n-marked text, write {count, plural, =0 {...} =1 {...} other {...}} for counts and {gender, select, female {...} male {...} other {...}} for string choices. Plural categories follow the locale's rules, other is the fallback, and clauses nest.

open as a page

In Angular i18n, why do generated message IDs churn between releases, and when are custom IDs the better choice?

level: middleimportance: must knowfreq 42%
basics
~20 s

A generated ID hashes the message text, placeholders included, plus its meaning, so any wording, markup or meaning change creates a new ID and orphans the old translation. Custom @@ids stay stable but can silently go stale.

open as a page

In Angular, how do you slide a toast notification in and out with animate.enter and animate.leave when an @if block toggles it?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Put animate.enter="toast-in" and animate.leave="toast-out" on the toast element inside @if. Angular adds the enter class when the element is inserted and removes it afterwards; on removal it adds the leave class and keeps the element until that animation ends.

open as a page

In Angular's legacy @angular/animations package, how do trigger(), state(), style(), transition() and animate() work together to animate a panel open and closed?

level: juniorimportance: must knowfreq 45%
basics
~20 s

trigger() names an animation bound in the template as [@name]; state() pairs a state value with the style() it rests in; transition() matches a change such as 'open <=> closed' and runs animate() steps. It needs provideAnimationsAsync() or an equivalent provider.

open as a page

In Angular's router, what does withViewTransitions() do during a navigation, and what happens in browsers without the View Transitions API?

level: juniorimportance: should knowfreq 32%
basics
~20 s

withViewTransitions() makes the router activate and deactivate routes inside document.startViewTransition, so the browser animates from a snapshot of the old page to the new one. Without View Transitions support, the router skips it and navigates normally.

open as a page

In Angular, how do you run animate.leave through a JavaScript function, and what happens if it never calls animationComplete()?

level: middleimportance: should knowfreq 32%
basics
~10 s

Bind (animate.leave)="fn($event)"; the handler gets an AnimationCallbackEvent with target and animationComplete(). Call animationComplete() when your animation finishes. If you never do, Angular removes the element after MAX_ANIMATION_TIMEOUT, 4000 ms by default.

open as a page

In Angular, when do animate.enter classes come off and when does animate.leave remove the element, with several animations or none at all?

level: middleimportance: should knowfreq 42%
basics
~20 s

Angular waits for the longest animation or transition on the element, counting its delay, then removes the enter classes or the leaving element. If the classes start no animation, it removes them, or the element, on the next frame instead of waiting.

open as a page

In Angular, what does TestBed.createComponent return, and how do you use that fixture to render and query the component?

level: juniorimportance: must knowfreq 70%
basics
~10 s

TestBed.createComponent returns a ComponentFixture: a handle exposing the component instance, its host element and a DebugElement tree. You let it render with await fixture.whenStable() or fixture.detectChanges(), then query nativeElement or debugElement.query(By.css(...)).

open as a page

In a new Angular CLI project, which builder and test runner does ng test use by default, and is Karma still supported?

level: juniorimportance: must knowfreq 52%
basics
~10 s

Since v21, new projects run ng test through the @angular/build:unit-test builder with Vitest in Node.js and jsdom; Karma with Jasmine is still supported, selectable with --test-runner=karma or the builder's runner option.

open as a page

In Angular, how do you unit-test a service that loads a user profile through HttpClient without sending a real network request?

level: juniorimportance: must knowfreq 66%
basics
~10 s

Add provideHttpClientTesting() to TestBed's providers, subscribe to the service call, then use HttpTestingController to expectOne the request, flush a canned body, assert the result, and call verify() so no unclaimed request remains.

open as a page

In Angular, how do you configure TestBed for a standalone component test, and what belongs in imports versus providers?

level: juniorimportance: must knowfreq 72%
basics
~10 s

Call TestBed.configureTestingModule with the standalone component and any modules it needs in imports and your service doubles in providers, then create it with TestBed.createComponent; a standalone component never goes in declarations.

open as a page

In a zone-based Angular test, how do you use fakeAsync and tick to prove a search input waits 300 ms after typing stops?

level: middleimportance: must knowfreq 55%
basics
~10 s

Wrap the test in fakeAsync, type with dispatchEvent, tick to just under 300 ms and assert nothing was searched, then tick the last millisecond, call detectChanges and assert the request and the rendered results.

open as a page

In Angular, what is the difference between ahead-of-time (AoT) and just-in-time (JIT) compilation, and why is AoT the default?

level: juniorimportance: must knowfreq 62%
basics
~20 s

AoT compiles Angular templates into JavaScript during the build; JIT ships the Angular compiler and compiles in the browser at runtime. AoT is the default because it starts faster, ships less code and reports template errors at build time.

open as a page

What can the Angular DevTools browser extension show you about a running app, and why does it refuse to work on a production build?

level: juniorimportance: must knowfreq 45%
basics
~20 s

Angular DevTools adds an Angular tab showing the component and directive tree with editable properties, the injector hierarchy with providers, and the router tree. It needs a development build, because optimized production builds strip the debug hooks it uses to talk to Angular.

open as a page

In an Angular 22 project, what does the strictTemplates compiler option check, and where is it configured?

level: juniorimportance: must knowfreq 52%
basics
~20 s

strictTemplates, set in angularCompilerOptions in tsconfig and on by default since Angular 22, makes the compiler type-check templates like TypeScript code: bindings against input types under strictNullChecks, typed $event and local references, and expressions inside embedded views.

open as a page

In Angular, what does the AoT compiler emit for a @Component class, and what are its static ɵcmp and ɵfac fields?

level: middleimportance: should knowfreq 36%
basics
~20 s

Angular's AoT compiler replaces @Component with static fields: ɵfac, a factory that creates the instance, and ɵcmp, the definition holding the selector, inputs and a template function of Ivy instructions that builds the DOM once and refreshes bindings on each check.

open as a page

From the browser console of an Angular app in development mode, how do you read and change a component's state with ng.getComponent and ng.applyChanges?

level: middleimportance: should knowfreq 32%
basics
~20 s

In development mode Angular publishes window.ng. Select the component's host element, call ng.getComponent($0) to get its instance, and change a field. A signal's set() schedules an update by itself; a plain field needs ng.applyChanges(instance) to mark it for check and run change detection.

open as a page

What are the main differences between AngularJS (1.x) and Angular, and is AngularJS still supported?

level: juniorimportance: must knowfreq 58%
basics
~20 s

AngularJS (1.x) is a JavaScript framework built on controllers, $scope and a digest loop of watchers; Angular is a TypeScript rewrite built on components, hierarchical dependency injection and top-down change detection. AngularJS support ended in January 2022.

open as a page

What does Angular's control-flow migration change in your templates, and what does it leave for you to review?

level: middleimportance: must knowfreq 55%
basics
~20 s

Angular's control-flow migration rewrites *ngIf, *ngFor and *ngSwitch into @if, @for and @switch and drops the now-unused directive imports. It leaves review work: identity tracking where no trackBy existed, kept ng-templates, CommonModule still imported, and templates it could not parse.

open as a page

Since Angular v22, how often does a new major version ship, and how long is each major supported?

level: middleimportance: must knowfreq 58%
basics
~20 s

Since v22 Angular ships a major roughly every 12 months, with 4-6 minors in between. Each major is supported for about 24 months: 12 months active, then 12 months of LTS that only takes critical and security fixes.

open as a page

You own a v15-era Angular codebase now updated to v22; in what order would you run the modernization schematics, feature by feature, and why?

level: seniorimportance: must knowfreq 46%
basics
~20 s

Run the optional schematics after the version update, one feature folder at a time: control flow, then the three standalone modes, then inject(), then the signal input, output and query migrations, and self-closing tags last, testing between each.

open as a page

Your Angular app is on v20 while v22 is current; how would you plan the upgrade, and why not jump straight to v22?

level: seniorimportance: must knowfreq 52%
basics
~20 s

Upgrade one major at a time, v20 to v21 then v21 to v22, because Angular's policy supports updates only within one major and ng update refuses multi-major jumps. v20's LTS ends 2026-11-28, so plan both hops before then.

open as a page