Skip to content

Instantly share code, notes, and snippets.

@harbirchahal
Last active October 16, 2022 14:58
Show Gist options
  • Save harbirchahal/04ba674ba3fc7ba6986e5123f1688d15 to your computer and use it in GitHub Desktop.
Save harbirchahal/04ba674ba3fc7ba6986e5123f1688d15 to your computer and use it in GitHub Desktop.
Computed value with Observable chains
class Observable {
constructor(val) {
this._value = val;
this._listeners = [];
}
get value() {
return this._value;
}
set value(val) {
if (this._value !== val) {
this._value = val;
this.notify();
}
}
notify() {
this._listeners.forEach(listener => listener(this._value));
}
subscribe(listener) {
this._listeners.push(listener);
}
}
class Computed extends Observable {
constructor(computeFn, observables) {
super('');
// Compute initial value
this._value = this._getComputedVal(computeFn, observables);
const listener = () => {
// Compute latest value
this._value = this._getComputedVal(computeFn, observables);
this.notify();
};
observables.forEach(observable => observable.subscribe(listener));
}
get value() {
return this._value;
}
set value(val) {
throw 'Cannot set computed value';
}
_getComputedVal(computeFn, observables) {
const values = observables.map(observable => observable.value);
return computeFn(...values);
}
}
const first = new Observable('John');
const last = new Observable('Doe');
const fullname = new Computed((firstVal, lastVal) => {
return `${firstVal} ${lastVal}`.trim();
}, [first, last]);
console.log(fullname.value); // John Doe
first.value = 'Jane';
console.log(fullname.value); // Jane Doe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment