Angular polling
Angular
Simple auto polling
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {switchMap, map} from 'rxjs/operators';
import {timer} from 'rxjs';
const REFRESH_INTERVAL = 2000;
export interface Player {
id: number;
first_name: string;
last_name: string;
}
export interface PlayerResponse {
data: Array<Player>;
}
@Injectable({
providedIn: 'root',
})
export class PlayerService {
constructor(private http: HttpClient) {}
api$ = this.http.get<PlayerResponse>('https://www.balldontlie.io/api/v1/players').pipe(
map((response) => {
return response.data;
}),
);
players$ = timer(0, REFRESH_INTERVAL).pipe(
switchMap(() => {
return this.api$;
}),
);
}
https://codesandbox.io/s/polling-api-call-zplybi?file=/src/app/app.component.html
Auto polling until response matches certain condition
- Use
expand
// delay 2s, and recursive call, but expand doesn't control the interval to make a new request
timer(2000).pipe(
switchMap(() =>
this.http.get<VcdTask>(taskUrl).pipe(
// make recursive http call until response.result is not null
expand((res) => {
return res.result === null
? this.http.get<VcdTask>(taskUrl).pipe(catchError(() => of({result: null} as VcdTask)))
: EMPTY;
}),
catchError(() => of({result: null} as VcdTask)),
takeLast(1), // take the matching not-null result only
),
),
);
- Use
internal
andtakeWhile
return interval(2000).pipe(
concatMap(() => this.http.get<VcdTask>(taskUrl)),
takeWhile((res) => res.result === null, true), // true is important!
);
throwError
andretry
this.http
.post(API, postData)
.pipe(
delay(2000),
concatMap((data) => {
this.saveData(data);
if (when_certain_condition) {
return throwError(() => new Error(''));
} else {
return of(data);
}
}),
retry(),
)
.subscribe();