Skip to content

RxJS, Signals and State Management Interview Questions for MEAN Stack

25 RxJS, Signals and State Management questions with answers for mean stack roles — 4 easy, 13 medium, 8 hard.

About RxJS, Signals and State Management

Reactive programming sits at the heart of Angular. This topic covers signals, computed, effect, linkedSignal and resource APIs, along with RxJS Observables, subjects, hot and cold streams, flattening operators like switchMap and exhaustMap, subscription cleanup and interop with toSignal. It also introduces NgRx Store and SignalStore for larger applications with complex shared state.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What are signals in Angular and why were they introduced?

Save to ▾
Show answer
A signal is a reactive value container: you read it by calling it, count(), and update it with set or update. Angular tracks which templates, computed values and effects read a signal, so when it changes only dependent parts update. Signals give fine-grained reactivity, enable zoneless change detection and are simpler than RxJS for synchronous component state. They are stable and central to modern Angular.
02

What is the difference between signal, computed and effect?

Save to ▾
Show answer
signal() creates writable state. computed() derives a read-only value from other signals, is lazily evaluated and memoised, and recalculates only when its dependencies change, for example a cart total from cart items. effect() runs side effects whenever signals it reads change, such as logging or syncing to local storage. Use computed for derived data and keep effects for non-UI side effects, not for setting other state.
03

What is RxJS and why is it important in Angular?

Save to ▾
Show answer
RxJS is a library for reactive programming with Observables, streams of values over time, combined using operators. Angular uses it in HttpClient, router events, reactive forms valueChanges and many third-party libraries. It excels at asynchronous workflows such as type-ahead search, polling, websocket streams, retries and combining multiple requests. Signals handle synchronous state well, while RxJS remains the tool for complex event streams.
04

Create a counter component with signal, computed and effect.

Save to ▾
Show answer
Signals keep simple state readable. import { Component, signal, computed, effect } from '@angular/core'; @Component({ selector: 'app-counter', template: ` <p>Count: {{ count() }} (double: {{ double() }})</p> <button (click)='increment()'>+</button> <button (click)='count.set(0)'>Reset</button> ` }) export class CounterComponent { count = signal(0); double = computed(() => this.count() * 2); constructor() { effect(() => console.log('count changed to', this.count())); } increment() { this.count.update((c) => c + 1); } }
05

What is the difference between a cold and a hot Observable?

Save to ▾
Show answer
A cold Observable starts producing values when each subscriber subscribes, and every subscriber gets its own independent execution; an HttpClient call is cold, so two subscriptions send two requests. A hot Observable produces values regardless of subscribers, and subscribers share the same stream, like mouse events or a websocket. You can make a cold Observable shared with operators like share or shareReplay.
06

What are Subject, BehaviorSubject, ReplaySubject and AsyncSubject?

Save to ▾
Show answer
A Subject is both an Observable and an observer, multicasting values to subscribers but giving late subscribers nothing from the past. BehaviorSubject needs an initial value and gives the latest value to new subscribers, popular for state like the current user. ReplaySubject replays a set number of past values. AsyncSubject emits only the final value on completion. In new code, signals often replace BehaviorSubject for state.
07

How do you avoid memory leaks from subscriptions in Angular?

Save to ▾
Show answer
Prefer the async pipe in templates or toSignal, which subscribe and unsubscribe automatically. For manual subscriptions, use takeUntilDestroyed() from the rxjs-interop package, which completes the stream when the component's DestroyRef fires. HttpClient requests complete on their own, but long-lived streams like intervals, store selectors, router events and websockets must be cleaned up. Avoid nested subscribe calls; use flattening operators instead.
08

How do toSignal and toObservable bridge RxJS and signals?

Save to ▾
Show answer
toSignal(observable$) subscribes to an Observable and exposes its latest value as a signal, unsubscribing automatically when the injection context is destroyed; you can supply an initialValue or requireSync. toObservable(signal) creates an Observable that emits whenever the signal changes, letting you apply RxJS operators like debounceTime and switchMap. Together they let you keep simple state in signals while using RxJS for async logic.
09

Implement a type-ahead search box that calls the API only after the user pauses typing and ignores outdated results. Which RxJS approach would you use?

Save to ▾
Show answer
Take the input stream from a FormControl's valueChanges or toObservable of a signal, then pipe debounceTime(300) to wait for a pause, map to trimmed text, filter out terms shorter than two characters, distinctUntilChanged to skip repeats, and switchMap to call the API, which cancels any in-flight request when a new term arrives. Add catchError inside switchMap so one failed request does not kill the stream.
10

Users double-click the Pay button and two payment requests are sent. How would you prevent it on the frontend?

Save to ▾
Show answer
Disable the button while the request is pending, using an isSubmitting signal. In RxJS, model clicks as a stream and use exhaustMap, which ignores new clicks until the current payment request completes. Show a loading state and handle errors so the button re-enables. The backend must still use idempotency keys, because frontend protection alone cannot stop network retries or duplicate tabs.
11

A dashboard needs data from three independent APIs before it can render. How would you load them?

Save to ▾
Show answer
Use forkJoin to run all three requests in parallel and emit once when all complete, giving an object or array of results. Handle errors per request with catchError returning a fallback value, so one failed widget does not block the whole dashboard. If any source emits repeatedly, use combineLatest instead. With signals, you could use three httpResource instances and a computed for the combined loading state.
12

A component subscribes to a service Observable in ngOnInit, and after navigating back and forth several times, the API is called multiple times per action. What is wrong?

Save to ▾
Show answer
The subscriptions are never cleaned up, so each visit adds another live subscriber that reacts to every emission. Use the async pipe or toSignal in the template, or add takeUntilDestroyed() to manual subscriptions. Also check that the service does not create a new long-lived stream per call and that nested subscribes are replaced with switchMap. Angular DevTools and network logs confirm the fix.
13

Write a type-ahead search using a reactive FormControl and RxJS operators.

Save to ▾
Show answer
switchMap cancels stale requests. export class SearchComponent { private api = inject(ProductService); search = new FormControl('', { nonNullable: true }); results = toSignal( this.search.valueChanges.pipe( debounceTime(300), map((t) => t.trim()), distinctUntilChanged(), filter((t) => t.length >= 2), switchMap((t) => this.api.search(t).pipe(catchError(() => of([])))) ), { initialValue: [] } ); } // template: <input [formControl]='search'> @for (p of results(); track p._id) {...}
14

Load three APIs in parallel with forkJoin and handle a failure in one of them.

Save to ▾
Show answer
Each request gets its own fallback. import { forkJoin, of, catchError } from 'rxjs'; loadDashboard() { return forkJoin({ sales: this.api.getSales().pipe(catchError(() => of(null))), orders: this.api.getRecentOrders().pipe(catchError(() => of([]))), users: this.api.getUserStats().pipe(catchError(() => of(null))) }); } dashboard = toSignal(this.loadDashboard()); // template: @if (dashboard(); as d) { ... d.sales ... } forkJoin emits once, after every inner Observable completes.
15

Write a cart service using signals with computed totals.

Save to ▾
Show answer
Expose read-only state and mutation methods. @Injectable({ providedIn: 'root' }) export class CartService { private items = signal<CartItem[]>([]); readonly cart = this.items.asReadonly(); readonly count = computed(() => this.items().reduce((n, i) => n + i.qty, 0)); readonly total = computed(() => this.items().reduce((s, i) => s + i.qty * i.price, 0)); add(product: Product) { this.items.update((list) => { const found = list.find((i) => i.id === product.id); return found ? list.map((i) => (i.id === product.id ? { ...i, qty: i.qty + 1 } : i)) : [...list, { ...product, qty: 1 }]; }); } remove(id: string) { this.items.update((l) => l.filter((i) => i.id !== id)); } }
16

Tell me about a time you fixed a difficult asynchronous bug.

Save to ▾
Show answer
Situation: users sometimes saw another customer's details after quickly switching between records. Task: find the cause in a busy sprint. Action: I reproduced it with network throttling and found nested subscribes, where slow responses for an earlier id arrived last. I replaced them with switchMap so stale requests were cancelled, and added a test with delayed responses. Result: the bug disappeared and we added a review rule against nested subscribes.
17

Describe a time you helped a teammate who was struggling with RxJS.

Save to ▾
Show answer
Situation: a new teammate kept writing nested subscribes and could not follow our streams. Task: help him become productive quickly. Action: I drew marble diagrams for map, switchMap and combineLatest, paired with him to refactor one of his components, and shared a short list of the operators we use most with examples. Result: within two weeks his pull requests used flattening operators correctly and he started reviewing others.
18

What is linkedSignal and when would you use it?

Save to ▾
Show answer
linkedSignal creates a writable signal whose value resets based on a source signal, while still allowing local updates. For example, selectedOption can default to the first item of an options list and reset when the list changes, but the user can still pick another option. It solves cases where computed is read-only and effect-based syncing would be awkward or cause extra change cycles.
19

What are the resource and httpResource APIs in Angular?

Save to ▾
Show answer
resource and httpResource bring asynchronous data into the signal world. You give them reactive parameters, such as a signal holding a product id, and they fetch data whenever those parameters change, cancelling stale requests. They expose signals like value, isLoading, error and status, and provide reload. httpResource builds on HttpClient, so interceptors still apply. They reduce manual subscribe-and-set code in components.
20

Explain the difference between switchMap, mergeMap, concatMap and exhaustMap.

Save to ▾
Show answer
All map each source value to an inner Observable but differ in concurrency. switchMap cancels the previous inner Observable, ideal for search. mergeMap runs all inner Observables in parallel, good for independent uploads. concatMap queues them and runs one at a time in order, good for sequential saves. exhaustMap ignores new values while one is active, ideal for preventing duplicate login or submit clicks.
21

What is NgRx and when is it worth using in an Angular application?

Save to ▾
Show answer
NgRx is a state management library family for Angular. NgRx Store follows the Redux pattern with actions, reducers, selectors and effects for side effects, giving predictable state and powerful DevTools. NgRx SignalStore offers a lighter, signal-based way to build stores with state, computed values and methods. It is worth it for large apps with complex shared state and many developers; small apps do fine with services and signals.
22

A shared service exposes state through a BehaviorSubject, and components mutate the emitted object directly, causing bugs. How do you redesign it?

Save to ▾
Show answer
Keep the writable state private and expose only a read-only view: asObservable() for a subject, or asReadonly() for a signal. Provide methods like addItem and removeItem that create new immutable objects with spread syntax and emit them. Immutable updates also work with OnPush change detection. Consider migrating the service to signals with computed selectors, or NgRx SignalStore for larger state.
23

You need to poll an order status API every five seconds until the order is delivered. How would you implement it?

Save to ▾
Show answer
Use timer(0, 5000) piped into switchMap to call the status API, then takeWhile(status => status !== 'delivered', true) to stop after the final status, including it. Add takeUntilDestroyed so polling stops if the user leaves, and retry with a delay for transient errors. For long waits, server-sent events or websockets are more efficient than polling, which wastes requests.
24

Use httpResource to load a product whenever the selected id signal changes.

Save to ▾
Show answer
The request reruns automatically when the id changes. import { Component, input } from '@angular/core'; import { httpResource } from '@angular/common/http'; @Component({ selector: 'app-product-detail', template: ` @if (product.isLoading()) { <p>Loading...</p> } @else if (product.error()) { <p>Could not load product</p> } @else if (product.value(); as p) { <h2>{{ p.name }}</h2> } ` }) export class ProductDetailComponent { id = input.required<string>(); product = httpResource<Product>(() => `/api/products/${this.id()}`); }
25

How would you convince your team to adopt signals in an existing RxJS-heavy codebase?

Save to ▾
Show answer
Situation: our team was hesitant to change working RxJS patterns. Task: I wanted to reduce subscription bugs and prepare for zoneless mode. Action: I built a proof of concept converting one complex component, measured fewer lines and change detection cycles, and proposed a gradual plan: signals for component state, RxJS kept for streams, toSignal at boundaries. Result: the team agreed to use signals in all new features.

Frequently asked questions

How important is RxJS, Signals and State Management in MEAN Stack interviews?

Reactive programming sits at the heart of Angular. This topic covers signals, computed, effect, linkedSignal and resource APIs, along with RxJS Observables, subjects, hot and cold streams, flattening operators like switchMap and exhaustMap, subscription cleanup and interop with toSignal. It also introduces NgRx Store and SignalStore for larger applications with complex shared state.

How should I use the RxJS, Signals and State Management sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.