One of Angular's most misunderstood concepts is observables. When they hear words like stream, subscribe, pipe, operator, and async pipe, many novices get confused.
However, when described in basic, useful terms, observables are not difficult.

This article explains Observables in plain English, demonstrating how they function within Angular and how they are used in practical applications.
1. What Exactly Is an Observable?
An Observable is a data stream.
Think of it as a pipe through which data flows over time.
Examples of data that come in a stream:
- API responses
- Button clicks
- Search input typing
- WebSocket updates
- Timer or interval updates
An Observable can send:
- One value
- Multiple values
- No value
- Or infinite values (like user clicks)
2. Observable vs Promise (Clear Difference)
| Feature | Observable | Promise |
| Multiple values |
Yes |
No |
| Can cancel |
Yes |
No |
| Lazy execution |
Yes |
No |
| Works with operators |
Yes |
No |
Simple comparison
- Promise gives you one response, like a courier delivering a parcel once.
- Observable is like a live news channel, sending updates continuously.
3. How Angular Uses Observables Everywhere
Observables are built into Angular:
| Angular Feature | Uses Observables |
|
HttpClient
|
Yes
|
|
Router events
|
Yes
|
|
Reactive Forms
|
Yes
|
|
Async Pipe
|
Yes
|
|
RxJS operators
|
Yes
|
|
WebSockets
|
Yes
|
So even if you don’t create an Observable yourself, Angular uses them internally.
4. Creating Your First Observable
This example sends three values and then completes.
const obs = new Observable(observer => {
observer.next('Hello');
observer.next('World');
observer.next('Angular');
observer.complete();
});
Subscribing:
obs.subscribe(value => console.log(value));
Output:
Hello
World
Angular
5. Using Observables With HttpClient (Most Common Case)
getUsers() {
return this.http.get<User[]>('/api/users');
}
Calling the method:
this.userService.getUsers().subscribe(data => {
this.users = data;
});
HttpClient returns an Observable because API data arrives asynchronously.
6. Understanding Subscription
Subscribing means:
- Start listening to the Observable
- Receive values
- React to them
Example
const subscription = this.getUsers().subscribe(data => {
console.log(data);
});
7. Why We Must Unsubscribe (Important)
If an Observable never completes (like events, WebSockets, intervals),
and you don't unsubscribe, memory leaks can occur.
Example
ngOnDestroy() {
this.subscription.unsubscribe();
}
But Angular gives easier solutions: async pipe.
8. Using Async Pipe (Best Practice)
Instead of:
this.users$.subscribe(...)
Use in template:
<li *ngFor="let user of users$ | async">{{ user.name }}</li>
Benefits:
- No unsubscribe required
- Cleaner templates
- Angular handles lifecycle automatically
9. RxJS Operators — Simple Explanation
Operators transform data inside the Observable pipeline.
Most used operators:
| Operator | What it does |
| map |
Transform value |
| filter |
Remove unwanted values |
| debounceTime |
Delay emissions (good for search) |
| switchMap |
Cancel previous request and switch to new one |
| catchError |
Handle errors |
Example search box:
this.searchControl.valueChanges.pipe(
debounceTime(300),
switchMap(text => this.api.search(text))
)
.subscribe(result => this.items = result);
10. Case Study: Building a Live Search
Step 1: Create a search form control
search = new FormControl('');
Step 2: Listen for typing
this.search.valueChanges.pipe(
debounceTime(500),
switchMap(keyword => this.service.search(keyword))
)
.subscribe(data => {
this.results = data;
});
Typing fast will not spam the API.
switchMap automatically cancels previous calls.
11. Case Study: Auto-Refresh Dashboard Data
interval(5000).pipe(
switchMap(() => this.api.getMetrics())
)
.subscribe(metrics => this.data = metrics);
This calls API every 5 seconds.
12. Case Study: Polling Until Condition Met
interval(1000).pipe(
switchMap(() => this.api.getStatus()),
filter(status => status === 'Completed')
)
.subscribe(() => console.log("Done"));
Real-world usage:
Tracking background job completion
Payment verification
File upload processing
13. Cold vs Hot Observables (Explained Simply)
Cold Observable
Starts fresh for each subscriber.
Example:
HttpClient, timers, intervals.
Hot Observable
Same stream shared with many subscribers.
Example:
User clicks, WebSocket messages.
14. Subjects: When You Need Manual Control
A Subject allows you to push values manually.
subject.next("Hello");
Use cases:
- Component-to-component communication
- Event bus
- Live updates from WebSocket
15. BehaviorSubject (Most Useful in Apps)
Stores last emitted value.
user$ = new BehaviorSubject(null);
updateUser(u) {
this.user$.next(u);
}
Useful for:
- Authentication state
- Theme state
- Cart state
16. ReplaySubject
Replays previous values to new subscribers.
Used for:
- Caching
- Remembering previous events
17. Best Practices for Observables in Angular
Do
- Use async pipe whenever possible
- Use operators instead of nested subscriptions
- Always unsubscribe for long-lived streams
- Group multiple subscriptions using takeUntil
- Keep Observables in services, not components
Avoid
- Subscribing inside services (return the Observable instead)
- Creating unnecessary Observables
- Shadowing Observables with same names
18. Summary
Observables become easy when you understand:
- They are streams of data
- You subscribe to start listening
- Operators modify the stream
- Async pipe reduces boilerplate
- Angular uses Observables everywhere
Observables are not complex. They are simply a powerful way to handle asynchronous programming in Angular.