Angular Observable vs Promise
Learn the differences between Angular Observables and JavaScript Promises with architecture diagrams, lifecycle, execution model, cancellation, RxJS operators, enterprise examples, best practices, and interview questions.
One of the most common Angular interview questions is:
What is the difference between an Observable and a Promise?
Although both handle asynchronous operations, they are designed for different use cases.
Angular primarily uses RxJS Observables because they are more powerful, flexible, and better suited for reactive applications.
Understanding the differences helps developers choose the appropriate abstraction for enterprise applications.
Table of Contents
- What is an Observable?
- What is a Promise?
- Observable vs Promise
- Execution Model
- Multiple Values
- Cancellation
- Lazy vs Eager Execution
- Operators
- Error Handling
- HttpClient and Observables
- Enterprise Banking Example
- Performance Best Practices
- Common Mistakes
- Top 10 Interview Questions
- Summary
What is an Observable?
An Observable is a stream of asynchronous values that can emit:
- Zero values
- One value
- Multiple values
- Errors
- Completion notifications
Observables are provided by RxJS.
Example
import { Observable } from 'rxjs';
const observable$ = new Observable<number>(observer => {
observer.next(10);
observer.next(20);
observer.next(30);
observer.complete();
});
Observable Architecture
flowchart LR
Observable
Observable --> Subscriber
Subscriber --> UI
What is a Promise?
A Promise represents the eventual completion (or failure) of a single asynchronous operation.
A Promise can have only one final outcome:
- Resolve
- Reject
Example
const promise =
new Promise<number>((resolve) => {
resolve(100);
});
Promise Architecture
flowchart LR
Promise
Promise --> Resolve
Promise --> Consumer
Observable vs Promise
| Feature | Observable | Promise |
|---|---|---|
| Values | Multiple | Single |
| Lazy | Yes | No |
| Cancelable | Yes | No (native Promise) |
| Operators | Rich RxJS operators | Limited chaining |
| Retry | Easy | Manual |
| Stream Processing | Excellent | Limited |
| Angular HttpClient | ✔ Yes | ✘ No |
| Reactive Programming | ✔ Yes | Limited |
Execution Model
Observable
Execution starts only when a subscriber exists.
const users$ =
this.http.get<User[]>(
this.api
);
// Nothing happens yet
users$.subscribe();
The HTTP request is sent only after subscribe().
Promise
Execution starts immediately after creation.
const promise =
fetch('/users');
The request begins immediately, even if no .then() is attached.
Execution Flow
flowchart TD
Observable
Observable --> Subscribe
Subscribe --> Execute
Promise
Promise --> ExecuteImmediately
Multiple Values
Observables can emit many values.
observer.next(10);
observer.next(20);
observer.next(30);
Output
10
20
30
Promises return only one result.
resolve(100);
Output
100
Multiple Value Architecture
flowchart LR
Observable
Observable --> Value1
Observable --> Value2
Observable --> Value3
Promise --> SingleValue
Cancellation
Observable
const subscription =
observable$
.subscribe();
subscription.unsubscribe();
Promise
promise.then(...);
Native Promises cannot be canceled once started. Some browser APIs (such as fetch) support cancellation through mechanisms like AbortController, but that capability is separate from the Promise itself.
Cancellation Flow
flowchart TD
Observable
Observable --> Subscribe
Subscribe --> Unsubscribe
Promise --> Execute
Execute --> Finish
Lazy vs Eager Execution
Observable
Create
↓
Wait
↓
Subscribe
↓
Execute
Promise
Create
↓
Execute Immediately
Observables are lazy.
Promises are eager.
Lazy Execution Architecture
flowchart LR
Observable
Observable --> Wait
Wait --> Subscribe
Subscribe --> Execute
RxJS Operators
Observables support powerful operators.
this.http
.get<User[]>(this.api)
.pipe(
map(users =>
users.filter(
u => u.active
)
),
catchError(error => {
return throwError(
() => error
);
})
);
Promises support basic chaining.
fetch('/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
Observables provide a much richer set of composition operators.
Operator Flow
flowchart LR
Observable
Observable --> map
map --> filter
filter --> switchMap
switchMap --> Subscriber
Error Handling
Observable
observable$
.subscribe({
next:value=>{
},
error:error=>{
console.error(
error
);
}
});
or
observable$
.pipe(
catchError(error => {
return throwError(
() => error
);
})
);
Promise
promise
.catch(error => {
console.error(
error
);
});
Error Handling Architecture
flowchart TD
Observable
Observable --> Error
Error --> catchError
catchError --> UI
Promise --> Catch
Angular HttpClient
Angular's HttpClient returns Observables instead of Promises.
Example
this.http
.get<User[]>(this.api)
.subscribe(users => {
console.log(users);
});
Why?
- Reactive programming
- Cancellation support
- RxJS operators
- Better composition
- Consistent Angular ecosystem
HttpClient Architecture
flowchart LR
Component
Component --> Service
Service --> HttpClient
HttpClient --> Observable
Observable --> Component
Converting Between Observable and Promise
Convert Observable to Promise
import {
firstValueFrom
} from 'rxjs';
const user =
await firstValueFrom(
this.http.get<User>(this.api)
);
Convert Promise to Observable
import {
from
} from 'rxjs';
const users$ =
from(
fetch('/users')
);
Note:
toPromise()has been deprecated in RxJS. PreferfirstValueFrom()orlastValueFrom()depending on your use case.
Enterprise Banking Example
Online Banking Dashboard
Observable Streams
- Live Balance
- Notifications
- Transactions
- Stock Prices
- Chat Messages
Promise Use Cases
- One-time configuration loading
- Initial application startup tasks
- Single asynchronous calculations
Architecture
flowchart TD
AngularApp
AngularApp --> BankingService
BankingService --> HttpClient
HttpClient --> Observable
Observable --> Dashboard
Dashboard --> Customer
Benefits
- Live updates
- Better responsiveness
- Stream processing
- Real-time applications
- Enterprise scalability
Performance Best Practices
| Practice | Benefit |
|---|---|
| Use Observables for Angular APIs | Consistent architecture |
| Prefer Async Pipe for UI | Automatic subscription management |
| Unsubscribe from long-lived streams | Prevent memory leaks |
| Use operators instead of nested subscriptions | Cleaner code |
Use firstValueFrom() only when a Promise is required |
Better interoperability |
| Avoid unnecessary conversions | Simpler codebase |
Common Mistakes
Converting Every Observable to Promise
Avoid unnecessary conversions.
Angular already provides Observables for HTTP, routing, and forms.
Forgetting to Unsubscribe
Long-lived Observables should be cleaned up appropriately.
Use:
- Async Pipe
takeUntil()- Angular lifecycle-aware cleanup mechanisms
Using Promise for Real-Time Data
Promises cannot emit multiple values.
Use Observables for:
- WebSockets
- Live Notifications
- Form Changes
- Event Streams
Using Nested Subscriptions
Prefer operators like:
switchMap()mergeMap()concatMap()
instead of deeply nested subscriptions.
Assuming Observables Execute Automatically
Observables are lazy.
Execution begins only after subscription (unless shared through other mechanisms).
Best Practices
- Use Observables throughout Angular applications.
- Use Promises for APIs that naturally return them or when integrating with non-RxJS libraries.
- Prefer Async Pipe in templates.
- Avoid unnecessary conversions.
- Use RxJS operators for composition.
- Handle errors consistently.
- Unsubscribe from long-lived streams.
- Keep reactive pipelines readable.
- Write unit tests for asynchronous logic.
- Choose the abstraction based on the problem, not preference.
Advantages
| Observable | Promise |
|---|---|
| Multiple emissions | Simple API |
| Lazy execution | Easy to understand |
| Cancelable | Native JavaScript |
| Rich operators | Good for one-time async work |
| Excellent for Angular | Widely supported |
Top 10 Observable vs Promise Interview Questions
1. What is the main difference between an Observable and a Promise?
Answer
An Observable can emit multiple values over time, while a Promise resolves or rejects only once.
2. Which one does Angular HttpClient use?
Answer
Angular HttpClient returns RxJS Observables.
3. Are Observables lazy?
Answer
Yes.
Observables begin execution only after a subscriber subscribes.
4. Are Promises eager?
Answer
Yes.
A Promise begins execution as soon as it is created.
5. Can Observables be canceled?
Answer
Yes.
Subscriptions can be canceled using unsubscribe().
6. Can Promises be canceled?
Answer
Native Promises cannot be canceled after they start. Some APIs that return Promises provide separate cancellation mechanisms, such as AbortController for fetch.
7. Why are Observables preferred in Angular?
Answer
Because they support multiple emissions, cancellation, RxJS operators, and integrate naturally with Angular features like HttpClient, forms, and routing.
8. How do you convert an Observable to a Promise?
Answer
Use firstValueFrom() or lastValueFrom().
9. When should you use a Promise?
Answer
Use a Promise for one-time asynchronous operations, especially when interacting with APIs that naturally return Promises.
10. What are Observable best practices?
Answer
- Prefer Observables in Angular.
- Use Async Pipe.
- Avoid nested subscriptions.
- Use RxJS operators.
- Unsubscribe from long-lived Observables.
- Convert to Promises only when necessary.
Interview Cheat Sheet
| Topic | Observable | Promise |
|---|---|---|
| Values | Multiple | Single |
| Execution | Lazy | Eager |
| Cancelable | ✔ Yes | ✘ Native Promise: No |
| Operators | RxJS | Limited |
| Angular HttpClient | ✔ Yes | ✘ No |
| Error Handling | catchError() / subscribe() |
.catch() |
| Best For | Streams & events | One-time async tasks |
| UI Integration | Async Pipe | Manual |
| Conversion | firstValueFrom() |
from() |
| Recommendation | Preferred in Angular | Use when appropriate |
Summary
Both Observables and Promises solve asynchronous programming problems, but they are optimized for different scenarios. Observables are the preferred choice in Angular because they support multiple emissions, lazy execution, cancellation, and powerful RxJS operators, making them ideal for HTTP requests, forms, routing, and real-time data streams. Promises remain useful for single asynchronous operations and interoperability with native browser APIs or third-party libraries.
Key Takeaways
- ✔ Observables can emit multiple values.
- ✔ Promises resolve only once.
- ✔ Observables are lazy.
- ✔ Promises are eager.
- ✔ Observables support cancellation through subscriptions.
- ✔ Angular HttpClient returns Observables.
- ✔ RxJS provides powerful stream operators.
- ✔ Use
firstValueFrom()instead of the deprecatedtoPromise(). - ✔ Prefer Observables for Angular applications.
- ✔ Observable vs Promise is one of the most common Angular interview topics.
Next Article
➡️ 72-RxJS-Operators-QA.md