Homemade observables
Tags: javascript, learning, reactiveprogramming
Published: 2018-08-12 01:30:40

---
title: Homemade observables
published: true
description: Making an observable from scratch (for educational purposes only)
tags: #javascript #learning #reactiveprogramming
---

> Puedes leer la versión en español [aquí](https://dev.to/vonheikemen/observables-hechos-en-casa-1bch).

On this episode we will build our own implementation of an observable. I hope that by the end of this post we gain a better understanding of this pattern that is used in libraries like RxJS.

## About Observables

### What is it?

Lets start with **my** definition of observable.

> An Observable is a function that follows a convention and is used to connect a data source with a consumer.

In our case a data source is something that produces values. And, a consumer is something that receives values from a data source.

### Fun facts

#### Observables are lazy

That means that they would not do any kind of work until it's absolutely necessary. Nothing will happen until you subscribe to them.

#### They can emit multiple values

Depending on the data source you can receive a finite number of values or an infinite stream of values.

#### They can be synchronous or asynchronous

It all depends on their internal implementation. You can setup an observable that process some stream of data in a synchronous way or create one from an event that can happen over time.

### Some rules

Remember when I said that observables follow a convention? Well, we are going to make our own arbitrary rules that our implementation will follow. These will be important because we are going to build a little ecosystem around our observables.

Here we go:

1. An observable instance will have a `subscribe` method.
2. The observable "factory" will take a `subscriber` function as a parameter.
3. The `subscriber` function will take an `observer` object as a parameter.
4. The `observer` object can implement these methods `next`, `error` and `complete`.

Now, lets do stuff.

### The code

### Factory function

```javascript
function Observable(subscriber) {
  return {
    subscribe: observer => subscriber(observer)
  };
}

// I swear to you, this works.
```

That is less magical than I thought. What we see here is that the **Observable** factory is just a way to postpone the work that has to be done until you call subscribe. The `subscriber` function is doing the heavy lifting, that's good because we can do whatever we want in there, is what will make our observables useful.

So far I haven't done a really good job explaining the `observer` and the `subscriber` roles. I hope it'll become clear when you see them in action.

## A use case

Say that we want to convert an array into an Observable. How can we do this?
 
Lets think about what we know: 

* We can do all of our logic inside the `subscriber` function.
* We can expect an observer object with three methods, `next`, `error` and `complete`

We can use the methods of the observer object as communication channels. The `next` function will receive the values that our data source gives us. The `error` will handle any errors we throw at it, it will be like the `catch` function in the `Promise` class. And, we will use the `complete` method when the data source is done producing values.

Our array to observable function could look like this.

```javascript
function fromArray(arr) {
  return Observable(function(observer) {
    try {
      arr.forEach(value => observer.next(value));
      observer.complete();
    } catch (e) {
      observer.error(e);
    }
  });
}

// This is how we use it

var arrayStream = fromArray([1, 2, 3, 4]);

arrayStream.subscribe({
  next: value => console.log(value),
  error: err => console.error(err),
  complete: () => console.info('Nothing more to give')
});

// And now watch all the action on the console
```

### Be safe

Right now the observer object is basically a lawless town, we could do all sorts of weird stuff like sending yet another value to `next` even after we call the `complete` method. Ideally our observables should give us some guarantees, like:

* The methods on the observer object should be optional.
* The `complete` and `error` methods need to call the unsubscribe function (if there is one).
* If you unsubscribe, you can't call `next`, `complete` or `error`.
* If the `complete` or `error` method were called, no more values are emitted. 

### Interactive example
We can actually start doing some interesting things with what we learned so far. In this example I made a helper function that let me create an observable from a DOM event.

{% codepen https://codepen.io/VonHeikemen/pen/wxNYPV %}

## Conclusion

Observables are a powerful thing, with a little bit of creativity you can turn anything you want into an observable. Really. A promise, an AJAX request, a DOM event, an array, a time interval... another observable (think about that for a second)... anything you can imagine can be a source of data that can be wrapped in an observable.

# Other sources
* [Learning Observable By Building Observable](https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87)
* [Observables, just powerful functions?](https://medium.com/@kevinkreuzer/observables-just-powerful-functions-a033c355b22c)

You can see part 2 of this post in [here](https://dev.to/vonheikemen/homemade-observables-part-2-composition-576f).

---

Thank you for reading. If you find this article useful and want to support my efforts, [buy me a coffee ☕](https://www.buymeacoffee.com/vonheikemen).

[![buy me a coffee](https://res.cloudinary.com/vonheikemen/image/upload/v1618466522/buy-me-coffee_ah0uzh.png)](https://www.buymeacoffee.com/vonheikemen)