Skip to content
Advertisement

attempting to poll a server however rxjs methods may be incorrect as algorithm breaks

so I am attempting to poll my server. I am trying to poll my server every 5 seconds. And the poll times out after one minute. I have a few console logs in the method for debugging but the only console.log that fires even after waiting 5 seconds is 'validate stream start'

I followed this tutorial without creating a separate service as I just need it for this one page in my application.

I’m willing to bet its a simple error or a misunderstanding in how these rxjs operators work.

What am I doing wrong?

startastream(){
    this.startastreamboolan = true;
    let count = 12;
    this.http.get(environment.shochat_content_creator_set_valid_stream_start)
      .subscribe((req: any)=>{
        console.log('validate stream start');
        timer(5000).pipe(
          switchMap(() =>{
            console.log('timer start');
            if(count > 0){
              return this.http.get(environment.check_if_stream_is_active_on_mux)
                .subscribe(
                  (req: any)=>{
                    this.streamready = true;
                    return 0;
                  },
                  error => {
                    count = count -1;
                    console.log(count);

                  });
            }
          }));
      });
  } 

Advertisement

Answer

timer

Creates an Observable that starts emitting after an dueTime and emits ever increasing numbers after each period of time thereafter.

timer(dueTime: number | Date = 0, periodOrScheduler?: number | SchedulerLike, scheduler?: SchedulerLike): Observable<number>

Its like interval, but you can specify when should the emissions start.

In your code, you are forgetting the second parameter of the timer operator, which means it will just wait for 5s and then emit only once. In addition, you are not subscribing to the timer, that’s why it’s not going any further. If you want to poll your server every 5s, you need to use :

timer(0, 5000)

Here, the timer won’t wait and will directly start emitting values every 5s.


Next, I see that you’re using a switchMap to create an inner stream, that’s great. But If your server takes more than 5s to process your request, you might want to use mergeMap instead as it doesn’t cancel the previous ongoing inner streams, it’s up to you.

The error here is that the switchMap (or the mergeMap) takes a callback function which must return an Observable, the operator will then subscribe to it by itself. Here, you are returning a Subscription instead.

Here is what you could do :

const start$ = this.http.get(startUrl).pipe(
  tap(() => console.log('Stream start'))
);
const poll$ = this.http.get(pollUrl).pipe(
  tap(() => (this.streamReady = true)),
  catchError(error => {
    console.log(error);
    return EMPTY;
  })
);

start$.pipe(
  switchMap(() => timer(0, 5000).pipe(
    tap(() => console.log('Polling every 5s')),
    mergeMap(() => poll$)
  ))
).subscribe();

I’ve created two Observables here. start$, which is responsible for starting the stream, and poll$, which is responsible for polling your server. The idea here is to start the stream, then switch to the timer inner stream which will emit every 5s, and then switch again to another inner stream that will poll the server.

I didn’t include the count in my example, so the stream will run forever with this code. You should take a look at the takeUntil operator for that purpose.

Hope it helped, feel free to ask questions !

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement