What is an Observable in Angular/RxJS?
1. What is an Observable?
An Observable is an RxJS object that represents a stream of data or events that can arrive over time.
A consumer can subscribe to an Observable to receive:
next— a new valueerror— an error occurredcomplete— the stream has finished
Simple definition
An Observable is a data stream that can emit zero, one, or multiple values over time, and subscribers can listen to those values.
For example:
Observable
│
├── 10
├── 20
├── 30
│
└── Complete
│
▼
Subscriber
In Angular, you commonly encounter Observables with:
HTTP requests
Form value changes
Route parameters
User events
Timers
WebSockets
2. Full Simple Sample Program
Let's first understand Observable without an HTTP API.
app.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-root',
standalone: true,
templateUrl: './app.html'
})
export class App {
message = '';
constructor() {
const message$ = new Observable<string>(subscriber => {
subscriber.next('Hello');
subscriber.next('Welcome to Angular');
subscriber.next('Learning RxJS Observable');
subscriber.complete();
});
message$.subscribe({
next: (value) => {
console.log(value);
this.message = value;
},
error: (error) => {
console.error(error);
},
complete: () => {
console.log('Observable completed');
}
});
}
}
app.html
<h1>Observable Example</h1>
<p>{{ message }}</p>
Console output
Hello
Welcome to Angular
Learning RxJS Observable
Observable completed
The page finally displays:
Learning RxJS Observable
because each emitted value replaces the previous message.
3. Understanding the Code
We created an Observable:
const message$ = new Observable<string>(subscriber => {
});
Observable<string> means:
This Observable emits values of type
string.
The $ in:
message$
has no special TypeScript meaning.
It is simply a common naming convention indicating:
This variable contains an Observable.
For example:
products$
users$
orders$
message$
4. Producing Values
Inside the Observable, we have:
subscriber.next('Hello');
subscriber.next('Welcome to Angular');
subscriber.next('Learning RxJS Observable');
next() sends values to subscribers.
So:
subscriber.next('Hello');
means:
Observable
│
│ "Hello"
▼
Subscriber
Three next() calls mean three values are emitted:
Observable
next("Hello")
│
▼
"Hello"
next("Welcome to Angular")
│
▼
"Welcome to Angular"
next("Learning RxJS Observable")
│
▼
"Learning RxJS Observable"
5. What is subscribe()?
Creating an Observable does not mean your component automatically receives its values.
You subscribe to it:
message$.subscribe({
next: ...
});
The subscriber listens for values emitted by the Observable.
Observable Subscriber
10 ───────────────────────► next(10)
20 ───────────────────────► next(20)
30 ───────────────────────► next(30)
Complete ─────────────────────► complete()
6. next, error, and complete
These are the three important Observable notifications.
next
Used when the Observable produces a value.
Producer:
subscriber.next('Hello');
Consumer:
next: (value) => {
console.log(value);
}
error
Used when something goes wrong.
For example:
const data$ = new Observable<string>(subscriber => {
subscriber.next('Processing');
subscriber.error('Something went wrong');
});
Subscribe:
data$.subscribe({
next: value => {
console.log(value);
},
error: error => {
console.error(error);
}
});
Output:
Processing
Something went wrong
After error(), the Observable terminates.
complete
Indicates that the Observable has finished producing values.
subscriber.complete();
Subscriber:
complete: () => {
console.log('Completed');
}
Once an Observable completes, it cannot emit additional values to that subscription.
So this doesn't deliver "Three":
subscriber.next('One');
subscriber.next('Two');
subscriber.complete();
subscriber.next('Three');
7. Observable Flow
The basic flow is:
Observable
│
│
subscriber.next()
│
▼
Subscriber
│
▼
next()
More completely:
Observable / Producer
│
├──── value ──────► next()
│
├──── value ──────► next()
│
├──── value ──────► next()
│
└──── complete ───► complete()
Subscriber
If an error occurs:
Observable
│
├── value
├── value
│
└── ERROR
│
▼
error()
8. Real Angular Example — HTTP Observable
This is where you'll frequently see Observables in Angular.
Suppose your ASP.NET Core Web API has:
GET /api/products
Angular:
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface Product {
id: number;
name: string;
price: number;
}
@Injectable({
providedIn: 'root'
})
export class ProductService {
private http = inject(HttpClient);
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(
'https://localhost:7001/api/products'
);
}
}
Notice:
Observable<Product[]>
This means:
getProducts()returns an Observable that will emit an array of products.
9. Subscribing to the HTTP Observable
Component:
products: Product[] = [];
ngOnInit(): void {
this.productService.getProducts()
.subscribe({
next: (data) => {
this.products = data;
},
error: (error) => {
console.error(error);
}
});
}
The flow is:
Component
│
│ getProducts()
▼
ProductService
│
│ http.get()
▼
Observable<Product[]>
│
│ subscribe()
▼
HTTP Request
│
▼
ASP.NET Core Web API
│
│ JSON Response
▼
Observable emits Product[]
│
▼
next(data)
│
▼
this.products = data
This is why you'll see Observables everywhere when Angular communicates with ASP.NET Core Web APIs.
10. Observable Can Emit Multiple Values
An important characteristic of Observables is that they can emit multiple values over time.
For example:
import { interval } from 'rxjs';
const timer$ = interval(1000);
timer$.subscribe(value => {
console.log(value);
});
Output:
0
1
2
3
4
5
...
One value is emitted every second.
Time →
0 ----- 1 ----- 2 ----- 3 ----- 4 -----
Observable stream
This makes Observables very useful for continuously changing data.
11. Observable with of()
We don't always need to manually write:
new Observable(...)
RxJS provides functions to create Observables.
One simple function is:
of()
Example:
import { of } from 'rxjs';
const numbers$ = of(10, 20, 30);
numbers$.subscribe(value => {
console.log(value);
});
Output:
10
20
30
Conceptually:
of(10, 20, 30)
│
▼
Observable
10 ─────► subscriber
20 ─────► subscriber
30 ─────► subscriber
12. Observable with Operators
Observables become especially powerful when combined with RxJS operators.
For example:
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
const numbers$ = of(1, 2, 3);
numbers$
.pipe(
map(number => number * 10)
)
.subscribe(value => {
console.log(value);
});
Output:
10
20
30
Flow:
Observable
1 → 2 → 3
│
▼
map(x => x * 10)
│
▼
10 → 20 → 30
│
▼
Subscriber
13. Observable vs Observer vs Subscriber
These terms can initially be confusing.
Observable
The source/producer of the data.
const numbers$ = of(10, 20, 30);
Observer
An object containing handlers such as:
{
next: value => console.log(value),
error: error => console.error(error),
complete: () => console.log('Completed')
}
Subscription
Calling:
numbers$.subscribe(...)
creates a subscription connecting the consumer to the Observable.
Conceptually:
Observable
│
│ values
▼
Observer
│
├── next()
├── error()
└── complete()
Subscription = active connection
14. Unsubscribing
When you subscribe:
const subscription = timer$.subscribe(value => {
console.log(value);
});
You can later stop receiving values:
subscription.unsubscribe();
For example:
const subscription = timer$.subscribe(value => {
console.log(value);
});
setTimeout(() => {
subscription.unsubscribe();
}, 5000);
After unsubscribing, the subscriber stops receiving values.
This matters particularly for long-lived streams such as:
interval()
WebSockets
form.valueChanges
custom Subjects
event streams
Angular also provides convenient lifecycle-aware approaches such as AsyncPipe and takeUntilDestroyed().
15. Observable vs Promise
This is a common interview question.
| Observable | Promise |
|---|---|
| RxJS concept | JavaScript concept |
| Can emit multiple values | Resolves/rejects once |
| Usually lazy | Eager once created |
| Supports many operators | Limited transformation APIs |
| Can unsubscribe | No direct unsubscribe |
| Excellent for streams | Good for one async result |
Example Observable:
const numbers$ = interval(1000);
It can produce:
0
1
2
3
4
...
A Promise represents a single eventual outcome.
16. Why Angular Uses Observables
Angular applications deal heavily with asynchronous operations.
For example:
GET Products
POST Order
Search box changes
Route parameter changes
Form changes
Button events
WebSocket messages
Timers
Observables provide a common model for handling these scenarios.
For example:
this.http.get<Product[]>(url)
returns:
Observable<Product[]>
while:
this.form.valueChanges
is also an Observable.
This means RxJS can process both using the same Observable/operator model.
Key Points
- An Observable represents a stream of data/events over time.
- Observable is one of the core concepts of RxJS.
- Observables can emit zero, one, or multiple values.
- Consumers receive Observable values by subscribing.
next()represents a new emitted value.error()represents failure and terminates the stream.complete()indicates that the stream has finished.subscribe()connects a consumer to an Observable.unsubscribe()stops an active subscription.- Angular
HttpClientreturns Observables. - Form
valueChangesis another common Angular Observable. - RxJS operators can transform and process Observable streams.
Easy way to remember
Observable = Stream
subscribe() = Start listening
next() = Receive value
error() = Something failed
complete() = Stream finished
unsubscribe() = Stop listening
Interview Questions and Answers
1. What is an Observable?
Answer:
An Observable is an RxJS object representing a stream of values or events over time. Consumers subscribe to the Observable to receive those values.
2. Can an Observable return multiple values?
Answer:
Yes. An Observable can emit zero, one, or multiple values over time.
of(10, 20, 30)
emits three values.
3. How do you receive values from an Observable?
Answer:
By calling subscribe().
numbers$.subscribe(value => {
console.log(value);
});
4. What are next, error, and complete?
Answer:
next → new value
error → stream failed
complete → stream finished
They represent the main notification types delivered by an Observable.
5. What does Angular HttpClient return?
Answer:
Angular HttpClient returns RxJS Observables.
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(url);
}
6. What is the difference between Observable and Promise?
Answer:
A Promise settles once with a single result or error, while an Observable can represent multiple values over time, supports RxJS operators, and can be unsubscribed.
7. Are Observables asynchronous?
Answer:
They can be asynchronous, but they are not necessarily asynchronous.
For example:
of(1, 2, 3)
emits synchronously, while HTTP requests and interval() involve asynchronous behavior.
This is an important interview distinction.
8. What is a Subscription?
Answer:
A Subscription represents the active execution created when you subscribe to an Observable.
const subscription = observable.subscribe(...);
It can be stopped using:
subscription.unsubscribe();
9. Why are Observables useful in Angular?
Answer:
They provide a consistent way to handle asynchronous and event-based operations such as HTTP requests, reactive form changes, route parameters, timers, and WebSocket messages.
10. What is an Observable in one interview sentence?
An Observable is an RxJS representation of a stream that can emit zero, one, or multiple values over time to subscribed consumers.