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. Prefer firstValueFrom() or lastValueFrom() 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 deprecated toPromise().
  • ✔ Prefer Observables for Angular applications.
  • ✔ Observable vs Promise is one of the most common Angular interview topics.

Next Article

➡️ 72-RxJS-Operators-QA.md