combineLatest reset observable - Rxjs

Viewed 880

I have 4 observables inside "combineLatest". What I need is that if observables 1, 3 or 4 emit a value, observable 2 resets its value. It's possible? Thank you

  1. Mat-table sort change event (Sort class)
  2. Mat-table change page event (PageEvent class)
  3. Custom observable (filter)
  4. Custom observable (other filter)
combineLatest($1, $2, $3, $4).subscribe(([a, b, c, d]) => CALL_HTTP_WITH_PARAMETERS(a, b, c, d))

Example (first values)

$1 = name,asc
$2 = 2
$3 = bla bla
$4 = bla bla

CALL_HTTP_WITH_PARAMETERS("name,asc", 2, "bla bla", "bla bla")

Observable 1 emit "name,desc" value

$1 = name,desc
$2 = 2 ==> has to be 1 again
$3 = bla bla
$4 = bla bla

CALL_HTTP_WITH_PARAMETERS("name,desc", 1, "bla bla", "bla bla")

Other

Observable 3 emit "new value" value

$1 = name,asc
$2 = 2 ==> has to be 1 again
$3 = new value
$4 = bla bla

CALL_HTTP_WITH_PARAMETERS("name,asc", 1, "new value", "bla bla")
2 Answers

You cannot reset the observable.

Think about what the observable is watching and change it.

For example:

merge($1, $3, $4).pipe(
   tap(_=> this.myGrid.setPage(1))
).subscribe()

Or, if it's out of your control, create Subject and use next.

For example:

subject2 = new Subject<number>();
$2 = this.subject2.asObservable();
onPageChanged(pageNumber:number){
   this.subject2.next(pageNumber);
}

merge($1, $3, $4).pipe(
   tap(_=> this.subject2.next(1))
).subscribe()

You can, Consider below strategy

Assume we have the Observables $a, $b, $c and $d, we will define these as Subjects.

We would like $a, $c and $d to reset $b. We can pipe theseObservables to reset $b

const $aSubject = new Subject()
const $bSubject = new Subject()
const $cSubject = new Subject()
const $dSubject = new Subject()
const $a = $aSubject.asObservable().pipe(
  tap(() => $bSubject.next(0))
)
const $b = $bSubject.asObservable()
const $c = $cSubject.asObservable().pipe(
  tap(() => $bSubject.next(0))
)
const $d = $dSubject.asObservable().pipe(
  tap(() => $bSubject.next(0))
)

Now we have managed to update $b on changes of the rest of the variables. Unfortunately this causes an infinite loop, as $b will always emit in the combineLatest() function. To solve this, we will pipe these Observable to the distinctUntilChanged operator.

The next problem to solve is extra httpCalls. Consider a situation where we change the first parameter which consequently updates the value of the second parameter. This will make 2 calls. We only need 1 call so we will use switchMap operator to cancel any earlier requests

combineLatest([$1, $2, $3, $4]).pipe(
  switchMap(([a, b, c, d])=> callHttp(a, b, c, d))
)

See this simple demo

Related