fixes initial loading of stats page
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { Component, OnInit, inject, AfterViewChecked, OnDestroy, ViewChild, ElementRef, NgZone } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, inject, AfterViewChecked, OnDestroy, OnInit, ViewChild, ElementRef, NgZone } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Chart, registerables } from 'chart.js';
|
||||
import { BaseChartDirective } from 'ng2-charts';
|
||||
import L from 'leaflet';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
import { StatsService } from '../services/stats.service';
|
||||
import {
|
||||
@@ -27,6 +28,7 @@ Chart.register(...registerables);
|
||||
})
|
||||
export class AdminStatsDashboardComponent implements OnInit, AfterViewChecked, OnDestroy {
|
||||
private readonly statsService: StatsService = inject(StatsService);
|
||||
private readonly cd = inject(ChangeDetectorRef);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
|
||||
@ViewChild('mapContainer', { static: false }) mapContainerRef!: ElementRef;
|
||||
@@ -82,10 +84,13 @@ export class AdminStatsDashboardComponent implements OnInit, AfterViewChecked, O
|
||||
// doesn't exist yet. ngAfterViewChecked detects when it appears.
|
||||
if (this.mapInitialized) return;
|
||||
if (!this.mapContainerRef) return;
|
||||
// Verify the native element actually exists in the DOM (not just that
|
||||
// the query ref was created — the @if block must have rendered too)
|
||||
if (!this.mapContainerRef.nativeElement?.isConnected) return;
|
||||
|
||||
this.mapInitialized = true;
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
// Defer one frame so the browser has laid out the container
|
||||
// Defer two frames so the browser has laid out the container
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => this._initMap());
|
||||
});
|
||||
@@ -187,22 +192,34 @@ export class AdminStatsDashboardComponent implements OnInit, AfterViewChecked, O
|
||||
const { start, end } = this.getDates();
|
||||
try {
|
||||
const [summary, timeSeries, geoStats] = await Promise.all([
|
||||
this._firstValue(this.statsService.getSummary(start, end)),
|
||||
this._firstValue(this.statsService.getTimeSeries(start, end)),
|
||||
this._firstValue(this.statsService.getGeoStats(start, end)),
|
||||
firstValueFrom(this.statsService.getSummary(start, end)),
|
||||
firstValueFrom(this.statsService.getTimeSeries(start, end)),
|
||||
firstValueFrom(this.statsService.getGeoStats(start, end)),
|
||||
]);
|
||||
|
||||
this.summary = summary;
|
||||
this.timeSeries = timeSeries;
|
||||
this.geoStats = geoStats;
|
||||
// Angular 17+ uses fetch-based HTTP whose promise resolutions run
|
||||
// outside the zone. Re-enter the zone and markForCheck() to force
|
||||
// change detection through the OnPush parent chain.
|
||||
this.ngZone.run(() => {
|
||||
this.summary = summary;
|
||||
this.timeSeries = timeSeries;
|
||||
this.geoStats = geoStats;
|
||||
|
||||
this._updateChart();
|
||||
this._updateMapMarkers();
|
||||
this._updateChart();
|
||||
this._updateMapMarkers();
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to load stats:', err);
|
||||
this.error = 'Failed to load stats data. Please check your connection and try again.';
|
||||
this.ngZone.run(() => {
|
||||
this.error = 'Failed to load stats data. Please check your connection and try again.';
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
} finally {
|
||||
this.loading = false;
|
||||
this.ngZone.run(() => {
|
||||
this.loading = false;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,11 +269,6 @@ export class AdminStatsDashboardComponent implements OnInit, AfterViewChecked, O
|
||||
});
|
||||
}
|
||||
|
||||
private _firstValue<T>(obs: import('rxjs').Observable<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
obs.subscribe({ next: (v) => resolve(v), error: reject });
|
||||
});
|
||||
}
|
||||
|
||||
// ── Chart ───────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user