Search code examples
angulartypescriptlong-polling

Long Polling in Angular 4


I need to do API calls to display the progress of something.

I have created a service which does this every 1.5 seconds

Main Component

private getProgress() {
        this.progressService.getExportProgress(this.type, this.details.RequestID);
    }

Services.ts

public getExportProgress(type: string, requestId: string) {
    Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .subscribe(
        (data) => {
            if (!data.InProgress)
                //Stop doing this api call
        },
        error => this.handleError(error));
}

The call works, but it keeps going. I want to stop doing the API call when the progress is finished (if (!data.InProgress) but I'm stuck on this.

How can I correctly unsubscribe from this observable when if (!data.InProgress)?

Thanks


Solution

  • You could use the takeWhile operator.

    Here is the documentation: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-takeWhile

    Emits values emitted by the source Observable so long as each value satisfies the given predicate, and then completes as soon as this predicate is not satisfied.

    Here is a generic example: https://rxviz.com/v/yOE6Z5JA

    Rx.Observable
      .interval(100)
      .takeWhile(x => x < 10)
      .subscribe(x => { console.log(x); });
    

    Here is an example with your code:

    public getExportProgress(type: string, requestId: string) {
        Observable.interval(1500)
            .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
            .map((data) => data.json().Data)
            .takeWhile((data) => data.InProgress)
            .subscribe(
            (data) => {
                ...
            },
            error => this.handleError(error));
    }