Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS 5, Angular: How to do a request every x seconds UNTIL a message matches a certain string?

New to Web-dev and Angular. Here is my current code. Right now, all it does is calling a http requests every 2seconds and console log the message. What I want is if the message matches to a string "5", let it unsubscribe. Also, how do i make this as non-nested subscribe? (is nested subcribe a bad practice?). Currently, i'm using Angular 5 and rxjs 5.

public checkProgress() {
   Observable
      .interval(2000)
      .subscribe(
        x => {
          this.myService.getStatus()
            .subscribe( data => console.log(data));
        }
      );
  }

Also, if a user navigate to a different component, how do I unsubscribe it? ngOnDestroy?

like image 710
NgoCuong Avatar asked Oct 24 '25 03:10

NgoCuong


2 Answers

There are multiple ways of doing it. Take your pick:

Recursion - one liner with ternary operator

expand(val => val === "5" ? this.myService.getStatus().pipe(delay(2000)) : empty())

Recursion with takeWhile

expand(() => this.myService.getStatus().pipe(delay(2000)))
    .pipe(takeWhile(val => val !== "5"))

Interval with takeWhile

timer(0, 2000)
    .pipe(
        switchMap(() => this.myService.getStatus()),
        takeWhile(val => val !== "5")
    )
like image 83
CozyAzure Avatar answered Oct 26 '25 16:10

CozyAzure


Use a subject to terminate the subscription with takeUntil

const { of, timer, Subject } = rxjs;
const { switchMap, takeUntil } = rxjs.operators;

const finalise$ = new Subject();
let finalised = false;

const finalise = () => {
  if (!finalised) {
    finalised = true;
    finalise$.next();
    finalise$.complete();
  }
};

const timer$ = timer(0, 2000); // Polling timer

const api$ = () => of(Math.random() * 5); // Simulate an api, just a random number

timer$.pipe(
  switchMap(_ => api$()),
  takeUntil(finalise$)
).subscribe(apiData => {
    console.log(apiData);
    if (apiData < 1) { // Condition to termitate
      finalise();
      console.log('finalised');
    }
});

// You can then call finalise in you OnDestroy method to kill the subscription
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.3.3/rxjs.umd.min.js"></script>
like image 41
Adrian Brand Avatar answered Oct 26 '25 15:10

Adrian Brand



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!