RxJS: Making simple variable as Observable

September 21, 2017

It is hard to build application with Angular without taking advantage of Observables. There is a bunch examples of handling http requests using them in the web.

Sometimes we need to use them to handle simple values. In the case it is usually implemented in a service. Service needs to provide Observable reference so components can subscribe for the updates. It requires at least two members declared in the service: Subject & Observable. Having half dozen observables in the service produces a dozen of declaration and makes code cluttered.

Implementation:

    
import { Observable, ReplaySubject, Subject } from "rxjs";

export class Subscribable<T> {

    private valueSource: Subject<T> = new ReplaySubject<T>(1);
    public value: Observable<T>;
    private _value: T;

    constructor() {
        this.value = this.valueSource.asObservable();
    }

    public set(val: T) {
        this.valueSource.next(val);
        this._value = val;
    }

    public get(): T {
        return this._value;
    }
}
    

It uses ReplaySubject to re-play only last change to the subscriber. There couple benefits of using this class:

Usage:

Subscribable<> should be declared in the service:

    
public isFullScreen: Subscribable<boolean> = new Subscribable<boolean>();

…
public setFullscreen(value: boolean) {
	this.set(value);
}

    

Value change can be handled in component:

    
this.service.isFullScreen.value.subscribe(res => { /*handle fullscreen*/ });
    

What else to consider:

In case last value should be “re - send” to observers:

    
public notify() {
    this.valueSource.next(this._value);
}
    

To send an error:

    
public error(message: any) {
    this.valueSource.error(message);
}