Thi's avatar
HomeAboutNotesBlogTopicsToolsReading
About|My sketches |Cooking |Cafe icon Support Thi
💌 [email protected]

RxJS discrete notes

Anh-Thi Dinh
AngularWeb DevJavaScript
Documentation
  • Learn RxJS ← well explained but not always up-to-date
  • Official site
  • Interactive diagrams of Rx Observables ← understand how things work visually
Be careful when using lastValueFrom and firstValueFrom
  • Only use firstValueFrom this with observables you know will emit at least one value, OR complete.
  • Only use lastValueFrom with observables you know will complete.
→ Most of the time, if you just get the first value from the observable, just try firstValueFrom!
It’s better to use “Subscribe Arguments”
👉 Official rxjs doc.
Knowing which is triggered in combineLatest
Theo mặc định thì ko có hàm chính thống, có thể thử
distinctUntilChanged()
👉 learnrxjs
toPromise to lastValueFrom or firstValueFrom
firstValueFrom & lastValueFrom
Observables
👉 Callbacks vs Promises vs RxJS Observable vs async/await
Observables represent a progressive way of handling events, async activity, and multiple values in JavaScript. Observables are really just functions that throw values. Objects called observers define callback functions for next(), error(), and complete(). ← ref
  • The function we pass to subscribe() gets executed whenever a new value is emitted.
  • Should read → 6 Simple Examples Which Will Make You Love Observables (rxjs 5)
    • The true power of rxjs → operators (bufferCount(3) ← eg, 3 clicks to show random numbers)
    • Use any other lib with rxjs, eg. transform any Promise to Observable by fromPromise
    • Smooth handling of HTTP request → eg. if there are many requests in a short time (we need the last will be treated) → race condition → subscribe the last, unsubsribe all previous → switchMap
  • Dùng cái này để theo dõi các đối tượng liên tục!!!! ← ref vn (thật ra cũng là dịch)
  • vs promise? → Everything you can do with a Promise you can do with an Observable. Everything you can do with an Observable you can't necessarily do with a Promise. (ref)
    • (Check the limit of promise above)
4 types of subjects
Good to read → Understanding rxjs BehaviorSubject, ReplaySubject and AsyncSubject
  1. Subject → No initial value or replay behavior. → 1 subject (multicast) to many observers. → example
  1. AsyncSubject → Emits latest value to observers upon completion. → only show when using sub.complete()
  1. BehaviorSubject → Requires an initial value and emits its current value (last emitted item) to new subscribers. → example & based on mouse clicks
      • Get current value? → either sub.value or sub.subcribe()
  1. ReplaySubject → Emits specified number of last emitted values (a replay) to new subscribers.
      • Need specify how many values / how long you wanna store "old" values.
Subject - Expected 1 arguments, but got 0
.pipe()
→ read this and official doc
Để tránh import toàn bộ rxjs/operators, chúng ta sẽ import những operators ta cần → tuy nhiên có những lúc (ví dụ clean hệ thống), ta vẫn import nhưng không dùng → pipe dùng để nhận biết cái nào được dùng và ignore những cái imported khác!
Subscription
  • Official doc
  • Good to red → Yet another way to handle RxJS subscriptions
combineLatest
👉 learnrxjs
Combine the “latest values” from 2 streams.
combineLatestAll (old: combineAll)
👉 learnrxjs | combineAll
switchMap
→ "switch to a new observable"
About|My sketches |Cooking |Cafe icon Support Thi
💌 [email protected]
1// deprecated
2of([1,2,3]).subscribe(null, null, console.info); // difficult to read
3// suggested change
4of([1,2,3]).subscribe({complete: console.info});
1// deprecated 
2throwError('I am an error').subscribe(null, console.error);
3// suggested change
4throwError('I am an error').subscribe({error: console.error});
1// recommended 
2of([1,2,3]).subscribe((v) => console.info(v));
3// also recommended
4of([1,2,3]).subscribe({
5    next: (v) => console.log(v),
6    error: (e) => console.error(e),
7    complete: () => console.info('complete') 
8})
1var trigger = "";
2
3Rx.Observable
4  .combineLatest(
5    s1.pipe(tap(() => (this.trigger = 's1'))),
6    s2.pipe(tap(() => (this.trigger = 's2')))
7	).subscribe(function(){
8    console.log("which is triggered? :", this.trigger);
9  });
1// Simple usage
2source$.pipe(distinctUntilChanged()).subscribe(console.log);
3
4// Custom comparer
5source$.pipe(distinctUntilChanged((prev, curr) => prev.name === curr.name)).subscribe(console.log);
1// Using lodash's things
2import { isEqual } from 'lodash';
3source$.pipe(distinctUntilChanged(isEqual).subscribe(console.log);
1// Old "toPromise()"
2public async loadCategories() {
3  this.categories = await this.service
4    .getCategories().toPromise()
5}
1// New "lastValueFrom"
2public async loadCategories() {
3  const categories$ = this.service.getCategories();
4  this.categories = await lastValueFrom(categories$);
5}
1const button = document.querySelector('button')
2const observable = Rx.Observable.fromEvent(button, 'click')
3observable.subscribe(event => {
4  console.log(event.target)
5})
1destroy$ = new Subject();
2constructor() {
3  this.destroy$.next(); // <-- Expected 1 arguments, but got 0.
4}
1new Subject<void>()
2// or
3this.destroy$.next(true);
1// instead of
2var$.tap().switchMap().catchError()
1// using pipe()
2var$.pipe( tap(), switchMap(), catchError() )
1import { combineLatest } from 'rxjs';
2combineLatest([a$, b$, c$]);