RxJS: Making simple variable as Observable
9/21/2017 by InstanceMaster
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 has 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:
Les code: only one member is declared in the class
Type control: ensures that only type from generic will be delivered to subscriber
Encapsulation: implementation is hidden, so you can experiment with different type of subjects or another notification mechanism
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);
}