The Angular Observable tutorial covers what is observable in Angular and how to use Observables in Angular applications. When we talk about Angular Observable, we hear a lot of terms like Reactive programming, data streams, Observable, Observers, RxJS, etc. It is very important to understand these terms before we start using the observables
Rx stands from Reactive programming. It is defined as programming with asynchronous data streams. So it is important that you understand what is data stream is.
Table of Contents
What is a data stream
A stream is a data, which arrives over a period of time. The stream of data can be anything. Like variables, user inputs, properties, caches, data structures, and even failures, etc
Consider the example of a sequence of x & y positions of mouse click events. Assume that user has clicked on the locations (12,15), (10,12), (15,20) & (17,15) in that order.
The following diagram shows how the values arrive over a period of time. As you can see stream emits the values as they happen i.e asynchronously.

Value is not the only thing that stream emits. The stream may complete as the user closes the window or app. Or an error may happen which results in the closure of the stream. At any point in time stream may emit any of the following three things
Value:
i.e the next value in the streamComplete:
The stream has endedError:
The error has stopped the stream.
The following diagram shows all the three possibilities in a stream

As said earlier the stream of data can be anything. For Example
- Mouse click or Mouse hover events with x & y positions
- Keyboard events like keyup, keydown, keypress, etc
- Form events like value changes etc
- Data which arrives after an HTTP request
- User Notifications
- Measurements from any sensor
Important Points regarding streams can
- emit zero, one or more values of any time.
- can also emit errors.
- must emit the complete signal, when completes (finite streams).
- can be infinite, that they never complete
Now, we have understood what is a data stream, let us look at what is Reactive Programming is
Reactive Programming
The reactive programming is all about creating the stream, emitting value, error or complete signals, manipulate, transfer or do something useful with the data streams.
This is where the RxJs comes into the picture
The introduction to Reactive Programming you’ve been missing gives you a very nice introduction to Reactive Programming. Also, refer to Introduction to Rx
What is RxJS
The RxJS (Reactive Extensions Library for JavaScript) is a javascript library, that allows us to work with asynchronous data streams
The Angular uses the RxJS library heavily in its framework to implement Reactive Programming. Some of the examples where reactive programming used are
- Reacting to an HTTP request in Angular
- Value changes / Status Changes in Angular Forms
- The Router and Forms modules use observables to listen for and respond to user-input events.
- You can define custom events that send observable output data from a child to a parent component.
- The HTTP module uses observables to handle AJAX requests and responses.
The RxJs has two main players
- Observable
- Observers ( Subscribers)
What is an Observable in Angular
Observable is a function that converts the ordinary stream of data into an observable stream of data. You can think of Observable as a wrapper around the ordinary stream of data.
Observable stream or simple Observable emits the value from the stream asynchronously. It emits the complete signals when the stream completes or an error signal if the stream errors out.
Observables are declarative. You define an observable function just like any other variable. The observable starts to emit values only when someone subscribes to it.
Who are observers (subscribers)
The Observable on its own is useless unless someone consumes the value emitted by the observable. We call them observers or subscribers.
The observers communicate with the Observable using callbacks
The observer must subscribe with the observable to receive the value from the observable. While subscribing it optionally passes the three callbacks. next()
, error()
& complete()

The observable starts emitting the value as soon as the observer or consumer subscribes to it.
The observable invokes the next()
callback whenever the value arrives in the stream. It passes the value as the argument to the next callback. If the error occurs, then the error()
callback is invoked. It invokes the complete()
callback when the stream completes.
- Observers/subscribers subscribe to Observables
- Observer registers three callbacks with the observable at the time of subscribing. i .e
next()
,error()
&complete()
- All three callbacks are optional
- The observer receives the data from the observer via the
next()
callback - They also receive the errors and completion events from the Observable via the
error()
&complete()
callbacks
Angular Observable tutorial
Now, we have learned the basics of the RxJs Observable, let us now see how it works using an example.
Create a new project in angular. Remove the contents from app.component.html
. Open the app.component.ts
Import the required libraries
RxJs library is installed automatically when you create the Angular project. Hence there is no need to install it.
Import the Observable from the rxjs library
1 2 3 | import { Observable } from 'rxjs'; |
Observable Creation
There are few ways in which you can create observable in angular. Simplest is to use the Observable constructor. The observable constructor takes observer (or subscriber) as its argument. The subscriber will run when this observable’s subscribe()
method executes.
The following example creates an observable of a stream of numbers 1, 2, 3, 4, 5
1 2 3 4 5 6 7 8 9 10 | obs = new Observable((observer) => { console.log("Observable starts") observer.next("1") observer.next("2") observer.next("3") observer.next("4") observer.next("5") }) |
The variable obs
is now of the type of observable.
The above example declares the obs
as the observable but does not instantiate it. To make the observable to emit values, we need to subscribe to it.

In the above example, we used the Observable Constructor to create the Observable. There are many operators available with the RxJS library, which makes the task of creating the observable easy. These operators help us to create observable from an array, string, promise, any iterable, etc. Here are list some of the commonly used operators
- create
- defer
- empty
- from
- fromEvent
- interval
- of
- range
- throwError
- timer
Subscribing to the observable
We subscribe to the observable, by invoking the subscribe
method on it. We can optionally, include the three callbacks next()
, error()
& complete()
as shown below
1 2 3 4 5 6 7 8 9 10 | ngOnInit() { this.obs.subscribe( val => { console.log(val) }, //next callback error => { console.log("error") }, //error callback () => { console.log("Completed") } //complete callback ) } |
The complete app.component.ts
code is as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { title = 'Angular Observable using RxJs - Getting Started'; obs = new Observable((observer) => { console.log("Observable starts") observer.next("1") observer.next("2") observer.next("3") observer.next("4") observer.next("5") }) data=[]; ngOnInit() { this.obs.subscribe( val=> { console.log(val) }, error => { console.log("error")}, () => {console.log("Completed")} ) } } |
Now, run the code and watch the debug window.
Adding interval
We can add a timeout to insert a delay in each next()
callback
1 2 3 4 5 6 7 8 9 10 11 12 | obs = new Observable((observer) => { console.log("Observable starts") setTimeout(() => { observer.next("1") }, 1000); setTimeout(() => { observer.next("2") }, 2000); setTimeout(() => { observer.next("3") }, 3000); setTimeout(() => { observer.next("4") }, 4000); setTimeout(() => { observer.next("5") }, 5000); }) |

Error event
As mentioned earlier, the observable can also emit an error. This is done by invoking the error()
callback and passing the error object. The observables stop after emitting the error signal. Hence values 4 & 5 are never emitted.
1 2 3 4 5 6 7 8 9 10 11 12 13 | obs = new Observable((observer) => { console.log("Observable starts") setTimeout(() => { observer.next("1") }, 1000); setTimeout(() => { observer.next("2") }, 2000); setTimeout(() => { observer.next("3") }, 3000); setTimeout(() => { observer.error("error emitted") }, 3500); //sending error event. observable stops here setTimeout(() => { observer.next("4") }, 4000); //this code is never called setTimeout(() => { observer.next("5") }, 5000); }) |
You can send the error object as the argument to the error method

Complete Event
Similarly the complete event. The observables stop after emitting the complete signal. Hence values 4 & 5 are never emitted.
1 2 3 4 5 6 7 8 9 10 11 12 13 | obs = new Observable((observer) => { console.log("Observable starts") setTimeout(() => { observer.next("1") }, 1000); setTimeout(() => { observer.next("2") }, 2000); setTimeout(() => { observer.next("3") }, 3000); setTimeout(() => { observer.complete() }, 3500); //sending complete event. observable stops here setTimeout(() => { observer.next("4") }, 4000); //this code is never called setTimeout(() => { observer.next("5") }, 5000); }) |

Observable Operators
The Operators are functions that operate on an Observable and return a new Observable.
The power of observable comes from the operators. You can use them to manipulate the incoming observable, filter it, merge it with another observable, alter the values or subscribe to another observable.
You can also chain each operator one after the other using the pipe. Each operator in the chain gets the observable from the previous operator. It modifies it and creates a new observable, which becomes the input for the next observable.
The following example shows the filer & map operators chained inside a pipe. The filter operator removes all data which is less than or equal to 2 and the map operator multiplies the value by 2.
The input stream is [1,2,3,4,5] , while the output is [6, 8, 10].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | obs.pipe( obs = new Observable((observer) => { observer.next(1) observer.next(2) observer.next(3) observer.next(4) observer.next(5) observer.complete() }).pipe( filter(data => data > 2), //filter Operator map((val) => {return val as number * 2}), //map operator ) |
The following table lists some of the commonly used operators
AREA | OPERATORS |
---|---|
Combination | combineLatest, concat, merge, startWith , withLatestFrom, zip |
Filtering | debounceTime, distinctUntilChanged, filter, take, takeUntil, takeWhile, takeLast, first, last, single, skip, skipUntil, skipWhile, skipLast, |
Transformation | bufferTime, concatMap, map, mergeMap, scan, switchMap, ExhaustMap, reduce |
Utility | tap, delay, delaywhen |
Error Handling | throwerror, catcherror, retry, retrywhen |
Multicasting | share |
Unsubscribing from an Observable
We need to unsubscribe to close the observable when we no longer require it. If not it may lead to memory leak & Performance degradation.
To Unsubscribe from an observable, we need to call the Unsubscribe()
method on the subscription. It will clean up all listeners and frees up the memory.
To do that, first, create a variable to store the subscription
1 2 3 | obs: Subscription; |
Assign the subscription to the obs
variable
1 2 3 4 5 6 7 | this.obs = this.src.subscribe(value => { console.log("Received " + this.id); }); |
Call the unsubscribe() method in the ngOnDestroy method.
1 2 3 4 5 | ngOnDestroy() { this.obs.unsubscribe(); } |
When we destroy the component, the observable is unsubscribed and cleaned up.
But, you do not have to unsubscribe from every subscription. For Example, the observables, which emits the complete signal, close the observable.
To learn more about it refer to the tutorial Unsubscribing from an Observable in Angular.
References
- observables
- RX-library
- observables in angular
- Practical observable usage
- Comparing observables
- Observable Design Pattern
Summary
Reactive programming is about programming the stream. The RxJS library brings Reactive Programming into Angular. Using RxJs, we can create an observable, which can emit the next value, error, and complete signals to the subscriber of the observable.
In the next few tutorials, we will learn more about the RxJs Observable
Read More
- Angular Tutorial
- Angular Observable Tutorial
- Create Observable from a string, array. object, collection
- Observable from events using fromEvent
- Observable pipe
- Map Operator
- Filter Operator
- Tap Operator
- SwitchMap
- MergeMap
- ConcatMap
- ExhaustMap
- take, takeUntil, takeWhile, takeLast
- First, last & Single
- Skip, SkipWhile, SkipUntil & SkipLast
- Scan & Reduce
- DebounceTime & Debounce
- Delay & DelayWhen
- ThrowError
- CatchError
- ReTry & ReTryWhen
- Unsubscribe from an observable
- Subjects in Angular
- ReplaySubject, BehaviorSubject & AsyncSubject
- Angular Subject Example
Very good tutorial…
Excellent introduction, I like to use BehaviorSubject or EventEmmitter for authentication
Really well explained and the precise content. Thank you!
wow, this is great, love that it is free but would pay for this!
No
This is a very good tutorial thank you
it’s a good post and very simple!. Thanks
Good tutorial. I find it very useful. tanx
Good article helped me a lot to understand observable.
The observer must subscribe with the observable to receive the value from the observervable
The observer receives the data from the observable (not observer) via the next() callback
I tried running your tutorial.
In the topic regarding observable completed with the code s below:
setTimeout(() => { observer.next(“1”) }, 1000);
setTimeout(() => { observer.next(“2”) }, 2000);
setTimeout(() => { observer.next(“3”) }, 3000);
setTimeout(() => { observer.complete() }, 3500); //sending complete event. observable stops here
setTimeout(() => { observer.next(“4”) }, 4000); //this code is never called
setTimeout(() => { observer.next(“5”) }, 5000);
the expected is for the next codes to stop. But actually, they are also excecuted when I tried it.
i am having same doubt. Did you find it?