fix(frontend): maintient le rafraichissement du tableau de bord en cas d'erreur
Sans catchError, la premiere reponse en erreur terminait le flux du timer : le rafraichissement ne repartait jamais et l'ecran restait fige sur des chiffres perimes, sans rien signaler. Le catchError porte sur l'observable interne du switchMap. Place sur le flux externe il terminerait le timer tout autant. Un signal error alimente un bandeau, efface des qu'une reponse valide revient.
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
import { Component, OnInit, inject, signal, DestroyRef } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { timer, switchMap } from 'rxjs';
|
||||
import { timer, switchMap, catchError, EMPTY, Observable } from 'rxjs';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { StatsService } from '../../core/services/stats.service';
|
||||
import { ConsumptionGauge } from '../../shared/components/consumption-gauge/consumption-gauge';
|
||||
import { SiteLoadChart } from '../../shared/components/site-load-chart/site-load-chart';
|
||||
import {AlertsService} from '../../core/services/alerts.service';
|
||||
import {StatsSummary} from '../../shared/models/stats.model';
|
||||
import {Alert} from '../../shared/models/alert.model';
|
||||
import { AlertsService } from '../../core/services/alerts.service';
|
||||
import { StatsSummary } from '../../shared/models/stats.model';
|
||||
import { Alert } from '../../shared/models/alert.model';
|
||||
|
||||
const REFRESH_INTERVAL_MS = 10000;
|
||||
const UNAVAILABLE_MESSAGE =
|
||||
'Données indisponibles, les valeurs affichées datent du dernier relevé.';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
@@ -25,15 +27,31 @@ export class Dashboard implements OnInit {
|
||||
|
||||
stats = signal<StatsSummary | null>(null);
|
||||
alerts = signal<Alert[]>([]);
|
||||
error = signal<string | null>(null);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.alertsService.getAlerts().subscribe((alerts) => this.alerts.set(alerts));
|
||||
this.alertsService
|
||||
.getAlerts()
|
||||
.pipe(catchError(() => this.reportUnavailable()))
|
||||
.subscribe((alerts) => this.alerts.set(alerts));
|
||||
|
||||
// Piège : le catchError porte sur l'observable interne. Sur le flux externe il
|
||||
// terminerait le timer, et le rafraîchissement ne repartirait jamais.
|
||||
timer(0, REFRESH_INTERVAL_MS)
|
||||
.pipe(
|
||||
switchMap(() => this.statsService.getSummary()),
|
||||
switchMap(() =>
|
||||
this.statsService.getSummary().pipe(catchError(() => this.reportUnavailable()))
|
||||
),
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe((stats) => this.stats.set(stats));
|
||||
.subscribe((stats) => {
|
||||
this.error.set(null);
|
||||
this.stats.set(stats);
|
||||
});
|
||||
}
|
||||
|
||||
private reportUnavailable(): Observable<never> {
|
||||
this.error.set(UNAVAILABLE_MESSAGE);
|
||||
return EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user