← Back to Articles         
What is an Observable in Angular/RxJS?

What is an Observable in Angular/RxJS?

Published on 01 Oct 2026     9 min read Angular
RxJS & Observables

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 value
  • error — an error occurred
  • complete — 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 HttpClient returns Observables.
  • Form valueChanges is 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.

← Back to Articles