I am coding a Single Page Application in Angular 5 and it requires to periodically check if API still has the same version as when the SPA was loaded to inform the user about the desync and allow her to refresh (the first call must be performed as soon as possible).
I have little experience working with rxjs and I know that if I am not careful I might end with unsubscribed observables and/or more HTTP calls than required.
My current code looks like this:
The service
import { Injectable } from "@angular/core";
import { IValidationResult } from "../models/validation-result";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs/Observable";
import { HttpClient } from "@angular/common/http";
@Injectable()
export class KeepAliveService {
checkVersion$: Observable<IValidationResult<string>>;
checkVersionSubscription: Subscription;
constructor(
private readonly httpClient: HttpClient) {
}
isUpToDate: boolean;
isLive = true;
liveVersion: string;
performCheckVersion(): void {
const localVersion = localStorage.getItem("MyAppLocalVersion");
this.checkVersion$ = this.httpClient.get<IValidationResult<string>>("GetApiVersion");
this.checkVersionSubscription = this.checkVersion$.subscribe(
(result: IValidationResult<string>) => {
this.liveVersion = result.payload;
this.isUpToDate = localVersion === this.liveVersion;
this.isLive = true;
this.checkVersionSubscription.unsubscribe();
});
}
}
Refreshing code (app.module.ts)
console.log("Quick version check");
this.keepAliveService.performCheckVersion();
console.log("Set check version setInterval");
setInterval(() => {
this.keepAliveService.performCheckVersion();
}, this.checkVersionInterval);
This does the job, but I feel it seems rather complex for such a simple job. Is there a "Observableish" way of obtaining the same functionality?
I have tried the following:
The service
import { Injectable } from "@angular/core";
import { IValidationResult } from "../models/validation-result";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs/Observable";
import { HttpClient } from "@angular/common/http";
import { interval } from "rxjs/observable/interval";
import { switchMap } from "rxjs/operator/switchMap";
startCheckingVersion() {
const httpObservable = interval(this.checkVersionInterval)
.switchMap(_ => this.httpClient.get<IValidationResult<string>>("GetApiVersion"));
this.checkVersionSubscription = httpObservable.subscribe(
(result: IValidationResult<string>) => {
const localVersion = localStorage.getItem("MyAppLocalVersion");
this.liveVersion = result.payload;
this.isUpToDate = localVersion === this.liveVersion;
this.isLive = true;
});
}
However, there is an issue related to how I use timer
and switchMap
as I received the following error:
timer_1.timer(...).switchMap is not a function ; Zone: ; Task: Promise.then ; Value: TypeError: timer_1.timer(...).switchMap is not a function
My package.json rxjs version:
"rxjs": "^5.5.6",