5 questions foundWhat is an observable in RxJS, and how is it different from a promise?
Beginner An observable represents a stream of values that can arrive over time, and you subscribe to it to receive those values as they happen. Unlike a promise, which resolves with exactly one value a single time, an observable can emit zero, one, or many values over its lifetime, and it can also be cancelled by unsubscribing.
import { of } from 'rxjs';
const numbers$ = of(1, 2, 3);
numbers$.subscribe((value) => console.log(value));
// Logs 1, 2, then 3
Real-world example A search feature uses an observable to represent a stream of user keystrokes over time, something a single promise could not naturally represent, since a promise only ever resolves once with one final value.
Common follow-ups: Why does an observable need to be subscribed to before it starts emitting values?;What happens to an observable's values if nothing ever subscribes to it?
HTTP Client & Interceptors;Angular Signals
What do the map, filter, and switchMap RxJS operators do, and when would you use each?
Intermediate map transforms each emitted value into something else, similar to the array method of the same name. filter only lets through values matching a specific condition. switchMap is used when an emitted value itself needs to trigger a new observable, such as a new HTTP request, automatically cancelling any previous still in progress request if a new value arrives first.
searchTerm$.pipe(
filter((term) => term.length > 2),
switchMap((term) => this.http.get(`/api/search?q=${term}`))
).subscribe((results) => this.results = results);
Real-world example A search box only sends a request once the user has typed at least three characters, and automatically cancels any still pending search request if the user keeps typing before it finishes, using filter and switchMap together.
Common follow-ups: Why does switchMap automatically cancel a previous still pending request, and why is that usually the desired behavior for search?;How does switchMap differ from mergeMap and concatMap?
HTTP Client & Interceptors;Forms
What is the difference between a Subject, a BehaviorSubject, and a ReplaySubject in RxJS?
Intermediate A plain Subject only emits values to subscribers that are already subscribed at the moment a value is sent, missing anything emitted before they subscribed. A BehaviorSubject always remembers and immediately emits its most recent value to any new subscriber, requiring an initial value. A ReplaySubject can remember and replay a specified number of past values to any new subscriber.
import { BehaviorSubject } from 'rxjs';
const currentUser$ = new BehaviorSubject<User | null>(null);
// A new subscriber immediately receives the current value, even if it was set before they subscribed
currentUser$.subscribe((user) => console.log('Current user is', user));
Real-world example A user session service uses a BehaviorSubject to track the currently logged in user, ensuring any component that subscribes later, even after login already happened, still immediately receives the correct current user value.
Common follow-ups: Why does a BehaviorSubject require an initial value while a plain Subject does not?;When would a ReplaySubject specifically be more appropriate than a BehaviorSubject?
State Management;Services & Dependency Injection
How would you combine two or more observables together, such as combining a user's search term and a selected filter category?
Advanced The combineLatest operator lets you combine the most recent values from several observables into a single observable, emitting a new combined value whenever any one of the source observables emits, letting you react to changes across multiple independent streams together.
combineLatest([searchTerm$, selectedCategory$]).pipe(
switchMap(([term, category]) => this.productService.search(term, category))
).subscribe((results) => this.results = results);
Real-world example A product search page automatically re runs its search whenever either the typed search term or the selected category filter changes, using combineLatest to react to both independent inputs together as a single combined stream.
Common follow-ups: How does combineLatest differ from the forkJoin operator, given both combine multiple observables?;What happens if one of the combined observables never emits a value at all?
Forms;State Management
Why is it important to unsubscribe from an RxJS observable, and what are common ways to do this correctly in Angular?
Intermediate Forgetting to unsubscribe from a long lived observable, such as one tied to a manually created subscription, can cause a memory leak, since the subscription and anything it references keeps existing even after the component using it is destroyed. Common solutions include using the async pipe, which unsubscribes automatically, or manually unsubscribing inside the ngOnDestroy lifecycle hook.
private subscription: Subscription;
ngOnInit() {
this.subscription = this.dataService.getData().subscribe((data) => this.data = data);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
Real-world example A live dashboard component correctly stops listening to a continuously updating data stream when the user navigates away, because it unsubscribes inside ngOnDestroy, avoiding a hidden, ongoing subscription that would otherwise keep running forever.
Common follow-ups: How does the takeUntil operator provide a cleaner way to manage unsubscribing from multiple observables at once?;Does every observable actually need to be manually unsubscribed, or do some complete automatically?
Lifecycle Hooks;Pipes (Built-in & Custom)