Skip to content

Instantly share code, notes, and snippets.

@phromo
Last active November 7, 2020 12:51
Show Gist options
  • Save phromo/ff6a6a8981cbd1f8f4b813f399056b1c to your computer and use it in GitHub Desktop.
Save phromo/ff6a6a8981cbd1f8f4b813f399056b1c to your computer and use it in GitHub Desktop.
// showcase using RxJs observables in Vue3
import { ref, Ref, readonly, watchEffect } from 'vue'
import { Subject, Observable } from 'rxjs';
import { scan } from 'rxjs/operators';
function rxToVue<T>(observable: Observable<T>, defaultValue: T): [Ref<T>, () => void] {
const obsRef = ref(defaultValue) as Ref<T>;
const subscription = observable.subscribe({next: (v) => obsRef.value = v})
// need to return subscription so it can be cancelled in onUnmounted
const stop = () => subscription.unsubscribe()
const roRef = readonly(obsRef) as Ref<T>
return [roRef, stop]
}
// example
const counterRx = new Subject<number>();
let counterScan = counterRx.pipe(scan(v => v + 1, 0))
const [vueCount, countStop] = rxToVue(counterScan, 0);
counterRx.next(1);
console.log("vue value", vueCount.value);
counterRx.next(1);
console.log("vue value", vueCount.value);
countStop();
counterRx.next(1);
console.log("vue value", vueCount.value);
// Output:
// vue value 1
// vue value 2
// vue value 2
// example 2: NOTE: an error occurs here, vue value 1 should had printed as well.
const [vueCount, countStop] = rxToVue(counterScan, 0);
watchEffect(() => console.log("vue value", vueCount.value));
counterRx.next(1);
counterRx.next(1);
// Output:
// vue value 0
// vue value 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment