Long Polling in Angular 4
Asked Answered
P

2

8

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

Pointed answered 13/10, 2017 at 11:30 Comment(0)
S
14

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));
}
Squilgee answered 13/10, 2017 at 12:38 Comment(0)
P
4

I've solved this by putting the service call in a variable, and unsubscribing from that variable when I'm done.

Here's the result:

public getExportProgress(type: string, requestId: string): any {
    let progress = Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .subscribe(
        (data) => {              
            if (!data.InProgress) {
                this.toastyCommunicationService.addSuccesResponseToast("done");
                progress.unsubscribe();
            }            
        },
        error => this.handleError(error));
}
Pointed answered 13/10, 2017 at 12:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.