DEV Community

Cover image for πŸš€ RxJS in Angular β€” Chapter 1 | What is RxJS? And What is an Observable?
Jack Pritom Soren
Jack Pritom Soren

Posted on

πŸš€ RxJS in Angular β€” Chapter 1 | What is RxJS? And What is an Observable?

What is RxJS? And What is an Observable?

πŸ‘‹ Welcome to the Series!

Hey there, Angular learner! πŸ‘‹

You've probably heard words like RxJS, Observable, subscribe, pipe… and thought:

"What is all this? Why does Angular use this? Do I really need this?"

YES. You absolutely need this. And by the end of this series, you will love it.

Let's start from the very beginning β€” zero assumptions, zero jargon. Just clear, simple, real-world understanding.


🍎 First, Let's Think About a Simple Story

Imagine you ordered a pizza online. πŸ•

You placed the order. Now you're just waiting. You didn't stand at the kitchen staring. You went and watched TV. Then, when the pizza arrived, the doorbell rang, and you responded.

That's exactly how RxJS Observables work.

  • You subscribe to something (like placing an order)
  • Something happens over time (the pizza is being made)
  • You react when data arrives (doorbell rings, you get the pizza)

πŸ“¦ What is RxJS?

RxJS stands for Reactive Extensions for JavaScript.

Think of it as a toolbox 🧰 full of tools to handle:

  • Data that comes over time (like user typing in a search box)
  • Data from the internet (like loading users from an API)
  • Events (like button clicks, form inputs)
  • Stuff that happens asynchronously (not immediately, but later)

Angular ships with RxJS built in. You don't install it separately. It's already there, waiting for you.


πŸ”­ What is an Observable?

An Observable is like a pipe through which data flows over time.

Let's use another story:

Imagine a water pipe in your house. The water company sends water through the pipe whenever you open the tap. You don't get all the water at once β€” it flows continuously as long as the tap is open.

An Observable works the same way:

  • It's a source of data
  • Data can come one item at a time or many items over time
  • You have to open the tap (subscribe) to receive water (data)
  • If you close the tap (unsubscribe), data stops flowing

πŸ§ͺ Let's See Real Code β€” Step by Step

Step 1: The Simplest Observable Ever

import { Observable } from 'rxjs';

// Creating an Observable β€” like setting up a water pipe
const myObservable = new Observable((observer) => {
  observer.next('Hello!');       // Send first value
  observer.next('How are you?'); // Send second value
  observer.next('Bye!');         // Send third value
  observer.complete();           // Done! No more data.
});
Enter fullscreen mode Exit fullscreen mode

What's happening here?

  • We created an Observable using new Observable(...)
  • Inside, we have an observer β€” think of it as the delivery person
  • observer.next(value) β€” sends a value down the pipe
  • observer.complete() β€” says "I'm done, no more values"

Step 2: Subscribe β€” Open the Tap!

myObservable.subscribe((value) => {
  console.log('Received:', value);
});
Enter fullscreen mode Exit fullscreen mode

Output:

Received: Hello!
Received: How are you?
Received: Bye!
Enter fullscreen mode Exit fullscreen mode

Until you call .subscribe(), nothing happens. The Observable just sits there. It's lazy! It only starts working when someone subscribes.

πŸ’‘ Key Insight: Observables are lazy β€” like a YouTube video that only plays when you press Play.


πŸ…°οΈ Real Angular Example β€” HTTP Requests

The most common place you'll see Observables in Angular is with HTTP calls.

When you fetch data from an API, Angular's HttpClient returns an Observable, not just a plain value.

Setting Up (app.module.ts)

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [HttpClientModule],
  // ...
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

The Service (user.service.ts)

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

export interface User {
  id: number;
  name: string;
  email: string;
}

@Injectable({
  providedIn: 'root'
})
export class UserService {

  private apiUrl = 'https://jsonplaceholder.typicode.com/users';

  constructor(private http: HttpClient) {}

  // This returns an Observable β€” data will arrive in the future!
  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.apiUrl);
    //         ^^^^ This is the Observable. Data isn't here yet!
  }
}
Enter fullscreen mode Exit fullscreen mode

The Component (user-list.component.ts)

import { Component, OnInit } from '@angular/core';
import { UserService, User } from './user.service';

@Component({
  selector: 'app-user-list',
  template: `
    <h2>πŸ‘₯ User List</h2>

    <!-- Show loading message while data is coming -->
    <p *ngIf="isLoading">Loading users... ⏳</p>

    <!-- Show error if something went wrong -->
    <p *ngIf="errorMessage" style="color: red;">{{ errorMessage }}</p>

    <!-- Show users when data arrives -->
    <ul *ngIf="!isLoading">
      <li *ngFor="let user of users">
        {{ user.name }} β€” {{ user.email }}
      </li>
    </ul>
  `
})
export class UserListComponent implements OnInit {

  users: User[] = [];
  isLoading = true;
  errorMessage = '';

  constructor(private userService: UserService) {}

  ngOnInit(): void {
    // πŸ”” HERE is where we SUBSCRIBE β€” we open the tap!
    this.userService.getUsers().subscribe({
      next: (data) => {
        // βœ… Data arrived! Store it.
        this.users = data;
        this.isLoading = false;
      },
      error: (err) => {
        // ❌ Something went wrong
        this.errorMessage = 'Failed to load users. Try again later.';
        this.isLoading = false;
      },
      complete: () => {
        // 🏁 Observable is done (optional to handle)
        console.log('All users loaded!');
      }
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

πŸŽ“ The Three Things an Observable Can Do

When you subscribe, you can listen for three things:

someObservable.subscribe({
  next: (value) => { /* Got a value! */ },
  error: (err)  => { /* Something broke 😱 */ },
  complete: ()  => { /* All done βœ… */ }
});
Enter fullscreen mode Exit fullscreen mode

Think of it like ordering food:

  • next β†’ "Your food is ready, here it is!" πŸ”
  • error β†’ "Sorry, we're out of that item." ❌
  • complete β†’ "Your entire order is delivered, we're done!" βœ…

🌊 Observable vs Promise β€” What's the Difference?

You may have used Promises before. Here's a simple comparison:

Promise β€” delivers one value, one time

// Like getting a single text message
const promise = fetch('/api/user').then(res => res.json());
Enter fullscreen mode Exit fullscreen mode

Observable β€” can deliver many values over time

// Like getting a WhatsApp conversation β€” message after message
const observable = this.http.get('/api/users'); // returns Observable
Enter fullscreen mode Exit fullscreen mode

Key differences:

  • A Promise executes immediately. An Observable is lazy (only runs when subscribed)
  • A Promise gives you one result. An Observable can give many results
  • An Observable can be cancelled (unsubscribed). A Promise cannot
  • Observables have superpowers β€” you can transform, filter, combine them (coming in later chapters!)

πŸ—οΈ Full Working Angular Example

Here's a complete mini-app that shows Observables in action:

user.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class UserService {
  constructor(private http: HttpClient) {}

  getUser(id: number): Observable<any> {
    return this.http.get(`https://jsonplaceholder.typicode.com/users/${id}`);
  }
}
Enter fullscreen mode Exit fullscreen mode

profile.component.ts

import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-profile',
  template: `
    <div *ngIf="user">
      <h2>{{ user.name }}</h2>
      <p>Email: {{ user.email }}</p>
      <p>Phone: {{ user.phone }}</p>
      <p>Website: {{ user.website }}</p>
    </div>

    <button (click)="loadUser(1)">Load User 1</button>
    <button (click)="loadUser(2)">Load User 2</button>
  `
})
export class ProfileComponent implements OnInit {
  user: any = null;

  constructor(private userService: UserService) {}

  ngOnInit(): void {
    this.loadUser(1); // Load user 1 by default
  }

  loadUser(id: number): void {
    this.userService.getUser(id).subscribe({
      next: (data) => this.user = data,
      error: (err) => console.error('Error loading user', err)
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

🎯 Real World Usage β€” Where You'll See Observables Every Day

Here are places you'll use Observables constantly in real Angular apps:

1. HTTP Requests β€” loading data from APIs

this.http.get('/api/products').subscribe(...)
Enter fullscreen mode Exit fullscreen mode

2. Router Events β€” detecting when navigation changes

this.router.events.subscribe(event => { ... })
Enter fullscreen mode Exit fullscreen mode

3. Form Value Changes β€” reacting when a user types

this.myForm.valueChanges.subscribe(value => { ... })
Enter fullscreen mode Exit fullscreen mode

4. Event Streams β€” button clicks, scroll events

fromEvent(button, 'click').subscribe(() => { ... })
Enter fullscreen mode Exit fullscreen mode

5. Timers β€” running code every few seconds

interval(3000).subscribe(() => console.log('3 seconds passed!'))
Enter fullscreen mode Exit fullscreen mode

⚠️ Common Mistake: Forgetting to Subscribe

// ❌ WRONG β€” Nothing happens! You forgot to subscribe!
this.userService.getUsers();

// βœ… CORRECT β€” Now it works!
this.userService.getUsers().subscribe(data => {
  this.users = data;
});
Enter fullscreen mode Exit fullscreen mode

If you forget to subscribe, the Observable just sits there doing nothing. It's like placing a pizza order but never giving them your address! πŸ•


🧠 Chapter 1 Summary β€” What You Learned

  • RxJS is a toolbox for handling data that arrives over time
  • Observable is a stream of data β€” like a pipe that sends values
  • You must subscribe to an Observable to receive its data
  • An Observable can emit next (values), error (problems), or complete (all done)
  • Angular's HttpClient returns Observables when making API calls
  • Observables are lazy β€” they don't do anything until subscribed
  • Observables are more powerful than Promises β€” they handle streams, not just single values

πŸ“š Coming Up in Chapter 2...

Now that you know what an Observable is, we're going to learn about subscribe() in detail β€” including the most important thing beginners miss: how to properly clean up subscriptions to prevent memory leaks!

See you in Chapter 2! πŸ‘‹


πŸ’Œ RxJS Deep Dive Newsletter Series | Chapter 1 of 10
Share this with a fellow Angular developer who's confused about RxJS!

Follow me on : Github Linkedin Threads Youtube Channel

Top comments (0)