Observables are like Supercharged Functions

A comparative look at observables and functions with examples

Image for post
Image for post
Photo by Maarten van den Heuvel on Unsplash

Introduction

RxJS observables are both powerful and heavily used in Angular. However, for most beginner developers, the concept of an Observable can seem overwhelming at first.

In this article, I will show you how observables are very much like the JavaScript functions that you are already familiar with except that observables are are much more powerful and flexible.

I use TypeScript for the code examples in this article but it should be okay to easily convert them to the equivalent JavaScript code.

Convert a function to an Observable

To stress the point that an Observable is just like a typical function we will first create a simple function then convert it to an Observable. We will extend this function as we proceed with the article to show other similarities.

The function below will simply combine or concatenate two string values, first-name and last-name then return the full-name.

public fullnameFunction(): string {
var firstname = 'Elon';
var lastname = 'Linga';
var fullname = firstname + " " + lastname;

return fullname;
}

We can easily convert the function above into an Observable and the code below shows how. Create a new Observable using the new observable() statement as follows.

Note: make sure to import Observable from ‘rxjs’

import { Observable } from 'rxjs';fullnameObservable = new Observable((subscriber)=> {
var firstname = 'Elon';
var lastname = 'Linga';
var fullname = firstname + " " + lastname;
subscriber.next(fullname);});

As you can see, the function and observable have exactly the same functionality. To return a value the function uses the return statement whereas an Observable uses the subscriber.next(return value) statement.

At this point, both the function and the Observable do the required functionality but they will not give us the result until we call them. This leads us to the next section, lazy computations.

Lazy computations

As you noticed above, although the function and observable have the logic to return a full-name. They do not give us the result value unless we trigger or ask them to do so. For this reason, they are both lazy computations.

The action of triggering a function is called invoking or calling a function. For an Observable it is known as subscribing.

For observables, the term subscribing is important because it denotes that you signup for the possibility to receive some value or service over a period of time or indefinitely until some party stops this process.

To call the function we created above and log the result to the browser console, we simply do the following.

var name = this.fullnameFunction();console.log(`The fullname from the function is: ${name}`);

the console log output should read The fullname from the function is: Elon Linga

As we mentioned earlier, to get a value from an observable we have to subscribe to it. To subscribe to the fullnameObservable we created above, we can do this.

this.fullnameObservable.subscribe((fullname)=> {
console.log(`The fullname from the observable is: ${fullname}`);
})

the console log output should read The fullname from the observable is: Elon Linga

Return a value(s)

As we have seen above both the observable and function are able to return some value. The difference however is that unlike functions that can only return a single value once, the Observable can return several values over time.

Think of it as having a function that can do this.

/* Note:this code code will work, it is only used as an example to stress a point */fullnameFunction(): string {
return “hi”;
return “my name is ”; return “Elon Linga”;}

As you might have guessed this will not work. A function can only return one value.

Observables, however, are more versatile and powerful and can return multiple value streams during their lifetime.

Extending the observable above to return multiple values, we can do the following.

import { Observable } from 'rxjs';fullnameObservable = new Observable((subscriber)=> {
var firstname = 'Elon';
var lastname = 'Linga';
var fullname = firstname + " " + lastname;
subscriber.next(firstname);
subscriber.next(lastname);
subsciriber.next(fullname);

});

Synchronous and asynchronous

Another important attribute with observables is that they can return values either synchronously or asynchronously. The observables we have looked at so far are all synchronous.

An Observable can also return value asynchronously. In the code below we use the JavaScript setTimeOut function to return an Observable value asynchronously.

import { Observable } from 'rxjs';fullnameObservable = new Observable((subscriber)=> {
var firstname = 'Elon';
var lastname = 'Linga';
var fullname = firstname + " " + lastname;
subscriber.next(firstname);
subscriber.next(lastname);
subsciriber.next(fullname);
setTimeout(() => {
subscriber.next("Async value here")
},5000);
});

The code within the setTimeout function above is async.

Conclusion

There you have it. Observables are very much similar to functions as you have seen. To recap, some important attribute of observables are that they

  • are lazily evaluated computations
  • can be synchronous or asynchronous and
  • can return multiple values over time or indefinitely

Written by

I develop software by profession. My interests include: history, economics, politics & enterprise-architecture. I am a child of God.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store