What the heck are Observables, Observers, Subjects and stream?

If you do not really understand what a Stream is, though it is out of the scope of this blog, but may be understanding Observables and Subjects would eventually give you an idea as to what a stream is. To start with, stream is actually a concept where the data arrives over time.

No more messing around, lets cut straight to the point.

To understand Observables, we first need to understand what a generator function is and how they relate to stream of data in the context of this blog.

Generator functions

A generator function holds all the value that it is supposed to send to the caller when called. Calling is done using the ‘next()’ method. A common generator function is as given below –

function* GiveMeSomeSunshine(){
     let state = 0;
     while (state < 5){
          // Below code can be thought of as an observer.
          // This will send value only when asked and till then
          // it will hold the execution.
          // Below code can be assumed as an Observer.
          yield "Here is your sunshine :D";
          state++;
     }
     return "enough of sunshine";
}


// Output:-
// ------------
var giveSunshine = GiveMeSomeSunshine();

giveSunshine.next(); // Here is your sunshine :D
giveSunshine.next(); // Here is your sunshine :D
giveSunshine.next(); // Here is your sunshine :D
giveSunshine.next(); // Here is your sunshine :D
giveSunshine.next(); // Here is your sunshine :D
giveSunshine.next(); // enough of sunshine

Here the function – ‘GiveMeSomeSunshine()’ holds all the value that it would be returning:

1. “Here is your sunshine :D”

2. “enough of sunshine”.

The function “GiveMeSomeSunshine” returns the message – “Here is your sunshine” only when it is asked for using – giveSunshine.next(), for which it returns the value with ‘done’ flag = False, and after which it halts the execution. It resumes the execution when it is asked for value again using – giveSunshine.next(), and after this it halts the execution again. The above function completes only when there are no more message to be returned, which happens when the business logic evaluates to false [while (state < 5)], and which is why, eventually the message – “enough of sunshine” is sent with the ‘done’ flag of generator as ‘True’.

Observables and Observers

In the code given above, the function ‘GiveMeSomeSunshine()’ can be thought of as an Observable, that returns the values when asked using the observer, which in the above case would be the the ‘giveSunshine’ object with next() method. Whenever observer.next() is called, a value is returned, provided the business logic evaluates to true.

Here, the observable (GiveMeSomeSunshine) has the data within itself which is sent on requirement (Observable.subscribe) basis. This is as essential functionality in modern web development. We need to have something that we can subscribe to and which can give us the data when we want/ or whenever it arrives over time. Observables are such functions, which you subscribe to, for it to listen to calls made for the data. When you do the call, it internally calls the next() method over the observer that Observable has. Below is a sample code for observable and how we can subscribe to it based on Angular 8 platform.

this.http.get("http://my-api-end-point.com/values").subscribe((observer) =>{
     console.log(observer.json());
});

Here we get the whole data as a response. Here the ‘get’ method returns an observable to which we are subscribing and writing an anonymous function to manipulate the data just as we want.

The observables doesn’t bring out its complete best in the above scenario, as here, the whole data is returned by the api at once and observable simply parses through it and returns it. The real essence of observable is felt when we are listening (hault execution unless asked ….next() on observer) for a value over time till it is unsubscribed().

Subjects

To make the best of Obervables, Subjects were introduced. They are Observables and Observers in itself. Which means, you can call the subscribe (Observable method) and next (Observer method) on Subjects. They have internal implementation to handle both.

Why was it done when we already had Observables with its observer, is because unless you are creating custom Observable, you do not have handle over the observer as to when should it be called. As soon as you subscribe to the default Observable, it will return Observer.next() implemented within. Subject, kind of, solves that problem of on demand subscription (which is normal just as with Observable) and on demand calling of next method (which can only be done on observer). This ensures us with more flexibility with the implementation.

Assume on a button click, user wants to view an image in pop-up which has functionality to render it based on image URL passed. So, when the application loads, the subject would be created, and subscribed to, but not called yet (no subject.next() called on page load). The next method can be called on the button click, which would send the image Url to the pop-up, which then renders the image from that url. We could also have an implementation where in on further clicks, different image Url would be sent. But for this we would not have to subscribe to the Subject again as it is already subscribed and it is just that the execution has halted until next is called again (like generator function next method). This can though of as listeners (not actually a listener) which listens for the next() method.

Now that we have understood that observables once subscribed, keeps listening to user request. Usually while coding, it so happens that multiple Observables (or Subjects – remember, subjects are Observables) are subscribed to and they keep listening even when they are no longer required. This causes leaks in memory. Hence, it is imperative to unsubscribe these Observables when they are no longer required. In angular, unsubscribe in ngOnDestroy.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s