0
0
Angularframework~15 mins

Creating observables in Angular - Mechanics & Internals

Choose your learning style9 modes available
Overview - Creating observables
What is it?
Creating observables means making special objects that can send out data over time. These objects let you watch for changes or events and react when they happen. In Angular, observables help manage things like user input, server responses, or timers in a clean way. They are like a stream of information you can listen to and use.
Why it matters
Without observables, handling data that changes over time would be messy and hard to follow. You would have to write complicated code to check for updates or wait for events. Observables make this easy and organized, so apps feel smooth and respond quickly. They help avoid bugs and make your code easier to understand and maintain.
Where it fits
Before learning to create observables, you should know basic Angular concepts like components and services, and understand JavaScript functions. After this, you can learn how to use observables with operators to transform data streams and how to manage subscriptions to avoid memory leaks.
Mental Model
Core Idea
An observable is like a radio station that broadcasts data over time, and you can tune in to listen and react whenever new data plays.
Think of it like...
Imagine a weather radio that continuously sends weather updates. You can turn it on to listen whenever you want, and it will keep giving you new information as it comes. Creating an observable is like setting up that weather radio station.
Observable Creation Flow:

┌───────────────┐
│ Create Source │
│ (data/events) │
└──────┬────────┘
       │ emits data over time
       ▼
┌───────────────┐
│  Observable   │
│ (stream of    │
│  data/events) │
└──────┬────────┘
       │ subscribers listen
       ▼
┌───────────────┐
│  Subscribers  │
│ (react to    │
│  data/events) │
└───────────────┘
Build-Up - 7 Steps
1
FoundationWhat is an Observable in Angular
🤔
Concept: Introduce the basic idea of an observable as a data stream that can emit values over time.
An observable is an object that can send out data or events to whoever is listening. In Angular, observables come from the RxJS library. They let you work with asynchronous data like clicks, HTTP responses, or timers. You create an observable to start this stream of data.
Result
You understand that observables are like data streams you can listen to and react when new data arrives.
Understanding observables as streams of data over time helps you think differently about handling asynchronous events compared to one-time values.
2
FoundationCreating a Simple Observable Manually
🤔
Concept: Learn how to create an observable from scratch using the Observable constructor.
You can create an observable by using the Observable constructor and defining how it sends data. For example: import { Observable } from 'rxjs'; const simpleObservable = new Observable(subscriber => { subscriber.next('Hello'); subscriber.next('World'); subscriber.complete(); }); This observable sends two messages and then finishes.
Result
You get an observable that emits 'Hello', then 'World', then completes.
Knowing how to create observables manually gives you full control over what data is sent and when, which is key for custom asynchronous logic.
3
IntermediateUsing Creation Functions for Observables
🤔
Concept: Discover built-in RxJS functions that create observables easily from common sources.
RxJS provides many helper functions to create observables without writing the constructor. Examples: - of(1, 2, 3): emits values 1, 2, 3 then completes. - from([10, 20, 30]): emits each array item. - interval(1000): emits increasing numbers every second. Example: import { of, interval } from 'rxjs'; const numbers$ = of(1, 2, 3); const timer$ = interval(1000);
Result
You can quickly create observables from arrays, values, or timers without manual setup.
Using creation functions saves time and reduces errors by providing ready-made observable sources for common patterns.
4
IntermediateCreating Observables from Events
🤔
Concept: Learn how to create observables that listen to DOM events like clicks.
You can create an observable that emits data when a user interacts with the page. For example, using fromEvent: import { fromEvent } from 'rxjs'; const button = document.querySelector('button'); const clicks$ = fromEvent(button, 'click'); clicks$.subscribe(event => console.log('Clicked!', event)); This observable emits a value every time the button is clicked.
Result
You get a stream of click events you can react to in real time.
Creating observables from events lets you handle user interactions reactively and declaratively.
5
IntermediateCreating Observables from HTTP Requests
🤔
Concept: Understand how Angular's HttpClient returns observables for server data.
Angular's HttpClient methods like get() return observables that emit the server response once ready. Example: this.http.get('https://api.example.com/data').subscribe(data => { console.log('Received:', data); }); This observable emits the HTTP response and then completes.
Result
You can handle server data asynchronously with observables, making your app responsive.
Knowing that HTTP calls return observables helps you integrate server data smoothly into your reactive Angular apps.
6
AdvancedControlling Observable Execution with Cold Observables
🤔Before reading on: Do you think observables start sending data immediately when created, or only when someone listens? Commit to your answer.
Concept: Learn that observables are 'cold' by default, meaning they only start emitting when subscribed to.
Observables do not do anything until you subscribe. This means creating an observable does not start data flow. For example: const obs$ = new Observable(subscriber => { console.log('Observable started'); subscriber.next(1); }); No output happens until obs$.subscribe() is called. This lets you define data streams without running them until needed.
Result
You understand that observables are lazy and only run when subscribed.
Knowing observables are cold prevents confusion about when data starts flowing and helps manage resources efficiently.
7
ExpertCustom Observable Creation with Teardown Logic
🤔Before reading on: Do you think observables automatically clean up resources when no longer needed, or do you have to handle it? Commit to your answer.
Concept: Discover how to add cleanup code to observables to release resources when subscribers unsubscribe.
When creating observables manually, you can return a function that runs when the subscription ends. This is called teardown logic. Example: const obs$ = new Observable(subscriber => { const id = setInterval(() => subscriber.next('tick'), 1000); return () => { clearInterval(id); console.log('Cleaned up'); }; }); When you unsubscribe, the interval stops and resources free up.
Result
Your observables properly clean up timers or event listeners, preventing memory leaks.
Understanding teardown logic is crucial for building efficient, leak-free Angular apps that use observables.
Under the Hood
Observables work by holding a function that defines how to produce values. When you subscribe, this function runs and sends data to the subscriber. The observable keeps track of subscribers and can send multiple values over time. It also supports cleanup by running teardown code when subscriptions end. Internally, observables use the observer pattern and lazy execution to manage asynchronous data streams efficiently.
Why designed this way?
Observables were designed to unify handling of asynchronous data like events, promises, and streams in a consistent way. The lazy execution model avoids unnecessary work until needed. Teardown logic was added to prevent resource leaks common in event-driven programming. RxJS, the library Angular uses, was created to provide powerful operators and composability for these streams.
Observable Internal Flow:

┌───────────────┐
│ Observable    │
│ (holds setup) │
└──────┬────────┘
       │ subscribe()
       ▼
┌───────────────┐
│ Subscriber    │
│ (receives     │
│  data/events) │
└──────┬────────┘
       │ sends data
       ▼
┌───────────────┐
│ Producer      │
│ (emits values │
│  over time)   │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Teardown     │
│ (cleanup on  │
│  unsubscribe)│
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does creating an observable start sending data immediately, or only after subscribing? Commit to your answer.
Common Belief:Creating an observable immediately starts sending data even if no one listens.
Tap to reveal reality
Reality:Observables are lazy and only start emitting data when subscribed to.
Why it matters:Assuming immediate execution can cause confusion and bugs when data seems missing or delayed.
Quick: Do you think observables automatically stop sending data when no longer needed, or do you have to manage it? Commit to your answer.
Common Belief:Observables clean up resources automatically without extra code.
Tap to reveal reality
Reality:You must provide teardown logic to clean up resources like timers or event listeners when unsubscribing.
Why it matters:Without cleanup, apps can leak memory or keep running unnecessary tasks, slowing down or crashing.
Quick: Can you use promises and observables interchangeably without changes? Commit to your answer.
Common Belief:Promises and observables are the same and can replace each other directly.
Tap to reveal reality
Reality:Promises handle a single value once, while observables can emit many values over time and support cancellation.
Why it matters:Confusing them leads to wrong code patterns and missed benefits of observables' streaming capabilities.
Quick: Do you think subscribing multiple times to the same observable shares the same data stream or creates new ones? Commit to your answer.
Common Belief:Multiple subscriptions share the same data stream automatically.
Tap to reveal reality
Reality:By default, each subscription creates a new independent execution (cold observable). Sharing requires special operators.
Why it matters:Not knowing this can cause unexpected repeated work or duplicated side effects.
Expert Zone
1
Creating observables manually allows precise control over when and how data is emitted, which is essential for complex asynchronous flows.
2
Teardown logic is often overlooked but critical for preventing subtle memory leaks in long-running Angular applications.
3
Cold observables start fresh for each subscriber, but hot observables share a single execution; understanding this distinction is key for performance tuning.
When NOT to use
Avoid creating observables manually for simple cases where RxJS creation functions like of(), from(), or fromEvent() suffice. Also, if you only need a single asynchronous value, consider using promises for simplicity. For shared data streams, use subjects or multicasting operators instead of raw cold observables.
Production Patterns
In real Angular apps, observables are created from HTTP calls, user events, and timers using RxJS helpers. Developers use operators to transform streams and manage subscriptions carefully with async pipes or takeUntil patterns to avoid leaks. Custom observables with teardown logic handle complex scenarios like WebSocket connections or manual event listeners.
Connections
Observer Pattern
Observables implement the observer pattern by letting observers subscribe to data changes.
Understanding the observer pattern clarifies how observables manage multiple subscribers and notify them of new data.
Reactive Programming
Creating observables is a core part of reactive programming, which focuses on data streams and propagation of change.
Knowing reactive programming principles helps you design apps that respond smoothly to asynchronous events using observables.
Event-Driven Systems (Computer Science)
Observables model event-driven systems by representing events as streams that can be observed and reacted to.
Seeing observables as event streams connects software design with real-world systems like user interfaces or network protocols.
Common Pitfalls
#1Creating an observable but never subscribing to it.
Wrong approach:const obs$ = new Observable(subscriber => { subscriber.next('data'); }); // No subscription here
Correct approach:const obs$ = new Observable(subscriber => { subscriber.next('data'); }); obs$.subscribe(value => console.log(value));
Root cause:Not understanding that observables are lazy and do nothing until subscribed.
#2Not cleaning up resources in custom observables causing memory leaks.
Wrong approach:const obs$ = new Observable(subscriber => { const id = setInterval(() => subscriber.next('tick'), 1000); // No cleanup function returned });
Correct approach:const obs$ = new Observable(subscriber => { const id = setInterval(() => subscriber.next('tick'), 1000); return () => clearInterval(id); });
Root cause:Ignoring teardown logic needed to stop ongoing processes when unsubscribing.
#3Assuming multiple subscriptions share the same observable execution.
Wrong approach:const obs$ = new Observable(subscriber => { console.log('Started'); subscriber.next(Math.random()); }); obs$.subscribe(console.log); obs$.subscribe(console.log);
Correct approach:import { share } from 'rxjs/operators'; const obs$ = new Observable(subscriber => { console.log('Started'); subscriber.next(Math.random()); }).pipe(share()); obs$.subscribe(console.log); obs$.subscribe(console.log);
Root cause:Not realizing cold observables create new executions per subscription; sharing requires operators.
Key Takeaways
Observables are lazy streams of data that only start emitting when subscribed to.
You can create observables manually or use RxJS helper functions for common data sources.
Teardown logic in observables is essential to clean up resources and avoid memory leaks.
Understanding cold versus hot observables helps manage how data is shared among subscribers.
Observables are a powerful foundation for reactive programming in Angular, enabling clean handling of asynchronous events.