Observables in Angular
π Observables in Angular – Complete Beginner’s Guide (with Examples)
π Introduction
In Angular, Observables are a core mechanism for handling asynchronous data streams. Built on top of the RxJS library, they help you react to changes over time—ideal for things like HTTP calls, form inputs, and real-time data updates.
π Table of Contents
- ✨ Key Features
- π Observable Lifecycle
- π§© Observable Callbacks
- ⚙️ RxJS Operators Example
- π Stream Lifecycle Table
- ✅ Best Practices
- π» Basic Example
- π§ͺ Extended Example
- π¦ Angular Service Example
- π― Why Use Observables?
- π Resources
✨ Key Features of Observables
- ✅ Emit multiple values over time
- ⏱ Lazy execution – runs only when
subscribe()is called - π« Cancelable using
unsubscribe() - π§ Works with RxJS operators like
map,filter,debounceTime - π¦ Used in Angular’s core:
HttpClient,Router,Forms - π§ Handles
next,error, andcomplete
π Observable Lifecycle
+----------+ +-----------+ +-------------+
| next() | --> | error() | --> | complete() |
+----------+ +-----------+ +-------------+
π§© Observable Callbacks
- next(value): Triggered when a value is emitted
- error(err): Triggered when an error occurs (e.g. 404 error)
- complete(): Triggered when the stream finishes
⚙️ RxJS Operator Chaining Example
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
of(1, 2, 3, 4).pipe(
filter(x => x % 2 === 0),
map(x => x * 10)
).subscribe(value => console.log(value));
Output: 20, 40
Tip: Operator chaining with pipe() makes complex logic easier to manage and test.
π Stream Lifecycle Table
| Method | When Called | Ends Stream? | Example Use Case |
|---|---|---|---|
next() |
Value emitted | ❌ | User input, HTTP response |
error() |
Error occurs | ✅ | Network failure |
complete() |
Stream ends cleanly | ✅ | File upload finished |
✅ Best Practices
- π Always unsubscribe manually or use
takeUntil() - π‘ Use the Angular
asyncpipe for auto-subscription - π§± Avoid nested subscriptions; use
switchMapormergeMap
π» Basic Example
import { Observable } from 'rxjs';
const obs = new Observable(observer => {
observer.next("First value");
setTimeout(() => observer.next("Second value"), 1000);
setTimeout(() => observer.complete(), 2000);
});
obs.subscribe({
next: val => console.log(val),
complete: () => console.log("Completed")
});
Output: First value → Second value → Completed
π§ͺ Extended Example with Error & Unsubscribe
import { Observable, Subscription } from 'rxjs';
const obs = new Observable(observer => {
observer.next("First value");
const t1 = setTimeout(() => observer.next("Second value"), 1000);
const t2 = setTimeout(() => observer.complete(), 2000);
return () => {
clearTimeout(t1);
clearTimeout(t2);
console.log("Unsubscribed");
};
});
const subscription = obs.subscribe({
next: val => console.log("Next:", val),
error: err => console.error("Error:", err),
complete: () => console.log("Stream completed")
});
setTimeout(() => subscription.unsubscribe(), 1500);
π¦ Angular Service and Component Example
// data.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class DataService {
getData(): Observable<string> {
return new Observable(observer => {
observer.next("First value");
const t1 = setTimeout(() => observer.next("Second value"), 1000);
const t2 = setTimeout(() => observer.complete(), 2000);
return () => {
clearTimeout(t1);
clearTimeout(t2);
console.log("Cleaned up");
};
});
}
}
// app.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { DataService } from './data.service';
@Component({
selector: 'app-root',
template: '<p>Check console for output</p>'
})
export class AppComponent implements OnInit, OnDestroy {
private subscription!: Subscription;
constructor(private dataService: DataService) {}
ngOnInit() {
this.subscription = this.dataService.getData().subscribe({
next: val => console.log("Received:", val),
error: err => console.error("Error:", err),
complete: () => console.log("Stream completed")
});
setTimeout(() => {
this.subscription.unsubscribe();
}, 1500);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
π― Why Use Observables?
Observables bring power and flexibility to async programming. Combined with RxJS, they simplify handling events, HTTP calls, and time-based workflows in Angular.

Comments
Post a Comment