Skip to content

Module 01: Foundations of RxJS

RxJS Mastery: Professional Course – Thinking in Streams

Module Version: 2.1 (Further Improved)
Last Updated: June 2026


Module Overview

Welcome to the very beginning of your journey to RxJS Mastery. This foundational module will rewire how you think about asynchronous code forever.

You will move from thinking in "callbacks and promises" to thinking in streams — a powerful mental model used by top frontend and full-stack engineers.

Estimated Total Time: 100–120 minutes (video + exercises) Difficulty: Beginner to Intermediate Prerequisites: Solid JavaScript/TypeScript fundamentals + basic understanding of async/await and Promises


Learning Objectives

By the end of this module you will be able to:

  • Clearly articulate the difference between imperative, promise-based, and reactive programming
  • Explain and implement the Observable contract (next, error, complete)
  • Confidently choose between cold and hot observables
  • Master the six most important creation operators
  • Build a fully functional reactive application from scratch

Lesson 1.1: The Philosophy of Functional Reactive Programming & RxJS Origins

Estimated Time: 15 minutes

Why This Matters

Most developers treat asynchronous code as an afterthought. RxJS forces you to treat time as a first-class citizen. This single shift dramatically reduces bugs in complex UIs, real-time features, and state management.

The Historical Lineage

  • 1997 – Functional Reactive Programming (FRP) born in Haskell
  • 2011 – Erik Meijer creates Rx.NET at Microsoft
  • 2012+ – RxJS is born and later modernized by Ben Lesh
  • Today – Core part of Angular and widely used in React/Vue ecosystems

Mental Model

"An Observable is a collection that arrives over time."

Instead of pulling data when you want it (arrays, promises), data is pushed to you when it becomes available.

Key Concept

RxJS = Observer Pattern + Iterator Pattern + Functional Programming


Lesson 1.2: The Observable Contract – next, error, complete

Estimated Time: 18 minutes

The Three Notifications

Every Observable can emit three types of notifications:

NotificationPurposeCan it happen multiple times?
nextDelivers a valueYes
errorTerminates with errorNo (stream ends)
completeGracefully ends the streamNo (stream ends)
  • Circles = next emissions
  • Vertical bar | = complete
  • X would represent error

This is the standard RxJS marble notation you will see throughout the course.

Quick Exercise

Create an Observable that emits 3 values, then errors. Observe both paths.

Key Takeaway: Always handle all three notifications in production code.

Managing Subscriptions (Critical for Production)

Every time you call .subscribe(), you create a Subscription. If you do not clean it up, you can leak memory and cause unexpected behavior.

ts
const sub = interval(1000).subscribe(console.log);

// Later, when you no longer need the stream:
sub.unsubscribe();

In real applications you will usually:

  • Use takeUntil(...) or take(1) inside the pipe
  • Store subscriptions and unsubscribe in ngOnDestroy (Angular) or useEffect cleanup (React)
  • Or use libraries like takeUntilDestroyed

We will go much deeper in Module 2, but you should start thinking about cleanup from day one.

Key Takeaway: subscribe() returns a Subscription — always have a strategy to stop it.


Lesson 1.3: Cold vs Hot Observables

Estimated Time: 20 minutes

The Critical Distinction

  • Cold Observable: Each new subscriber gets its own independent execution. (Default behavior)
  • Hot Observable: All subscribers share the same execution (uses Subjects or multicasting).

Real-World Analogy

  • Cold = Netflix — every viewer starts the movie from the beginning
  • Hot = Live sports — everyone watches the same moment in real time

Why It Matters

Using the wrong type can cause:

  • Memory leaks (too many cold subscriptions)
  • Missed values (subscribing too late to a hot stream)
  • Unexpected duplicate API calls

Lesson 1.4: Creation Operators Masterclass

Estimated Time: 22 minutes

The Six Essential Creation Operators

OperatorUse CaseExample Use
of()Emit static valuesConstants, test data
from()Convert arrays, promises, iterablesAPI responses, arrays
interval()Emit sequential numbers over timePolling, timers
timer()Emit after a delayDelayed actions
fromEvent()DOM / Node.js eventsClick, input, WebSocket
ajax()HTTP requests (with cancellation)REST API calls

Pro Tips

  • Use from(array) when you want each array element emitted separately; use of(array) when the array itself is the value
  • Use ajax() or fromFetch()/AbortController when HTTP cancellation matters; native fetch() only cancels if you wire abort support
  • Combine timer(0, 1000) for "immediate + repeating"

Common Mistake

Using new Observable() when a creation operator exists — hurts readability and tree-shaking.

Quick Exercise

Create an Observable from a Promise that resolves after 2 seconds.

Key Takeaway: Creation operators are your entry point into the reactive world.


End-of-Module Quiz

5 Multiple Choice Questions (Improved)

  1. What happens if you subscribe to a cold Observable multiple times?

    • A) All subscribers share the same execution
    • B) Each subscriber gets its own independent execution
    • C) Only the first subscriber receives values
    • D) The stream throws an error
  2. Which notification always ends an Observable stream?

    • A) next
    • B) error and complete
    • C) Only complete
    • D) Only error
  3. You should convert a cold Observable to hot when...

    • A) You want to avoid duplicate expensive operations
    • B) You want every subscriber to start from the beginning
    • C) You are working with static values
    • D) You want better TypeScript support
  4. What is the main advantage of RxJS HTTP helpers like ajax()/fromFetch() over a bare fetch() Promise?

    • A) Faster requests
    • B) Observable teardown can abort the request when the helper wires cancellation
    • C) Better error messages
    • D) Built-in caching
  5. In the Live Number Stream Dashboard project, which operator combination keeps a rolling window of the last 10 numbers?

    • A) map + filter
    • B) scan + slice
    • C) mergeMap + take
    • D) debounceTime + distinctUntilChanged

Correct Answers: 1-B, 2-B, 3-A, 4-B, 5-B

Explanations:

  • Q1: Cold observables are independent per subscriber.
  • Q2: Both error and complete terminate the stream.
  • Q3: Hot observables share expensive work (e.g. one HTTP call for many components).
  • Q4: ajax() and fromFetch() return Observables whose teardown is wired to request cancellation; a bare fetch() Promise needs explicit AbortController handling.
  • Q5: scan accumulates the history array; the logic keeps a maximum of the last 10 values using array slicing inside the accumulator.

Module Summary & Next Steps

You now understand the foundational building blocks of RxJS:

  • The Observable contract + proper subscription management
  • Cold vs Hot behavior
  • Creation operators
  • How to build clean, leak-free reactive UIs using proper stream control

Next Module: Module 02 – Core Concepts (Observer vs Iterator, Marble Diagrams, Schedulers Deep Dive)

Recommended Practice: Rebuild the Live Number Stream Dashboard from memory without looking at the code. Pay special attention to how the subscription is managed.


Created with SuperGrok · Released under the MIT License.