Observables are first-class citizens in the Angular ecosystem. They are abundant in the Angular API which represents HTTP requests, routing events and whatnot as streams of data. It may have been a controversial design choice, but it paid off.

But it turns out that the pattern fits so well into the current state of affairs in the front-end environment that it might one day become part of the ECMAScript standard library. So whether you like it or not, Angular encourages you to think in observables, which turns after a while your entire codebase into a bunch of map, flatMap and filter operators.

If all you have is a hammer, everything looks like a nail.

Now that we see observables everywhere, we can try to apply the reactive pattern to familiar Web APIs. And if some concepts like document title or DOM manipulation were abstracted out in the corresponding modules, localStorage is not among them. Therefore it seems natural to implement localStorage as a reactive service with the following interface:

export interface ILocalStorage {
  select(key: string, defaultValue: any = null): Observable<any>;
  set(key: string, value: any): void;
  remove(key: string): void;
}

In contrast to the common localStorage, our service exposes a selector (inspired by redux) that returns an observable for a given key. Internally we maintain a list of BehaviorSubject instances (companion of the RxJS Subject that in addition to being a Subject also exposes the current value). Whenever a new value was pushed into the subject in the set method, selector with the corresponding key emits it.

The entire implementation of our modest service might look like this: