Tengo consultas de bases de datos que se ejecutan y devuelven datos del servidor. Cuando los datos devuelven mi suscripción funciona. Si llamo a refreshData las consultas se ejecutan nuevamente y devuelven datos, sin embargo, la suscripción en AnotherComponent no se ejecuta la segunda vez.
Creo que esto se debe a take(1) , que toma un elemento y finaliza la suscripción. ¿Hay alguna manera de que pueda finalizar el intervalo, pero mantener la suscripción activa en AnotherComponent ?
Nota: Decidí usar un intervalo porque algunos elementos se suscriben demasiado tarde y nunca reciben los datos iniciales.
No creo que un ReplaySubject sea el camino a seguir porque no me importa cuáles fueron los datos anteriores.
Este servicio realiza las consultas iniciales de las aplicaciones necesarias para cargar una página.
export class StartupGraphqlService { private initCalled = false; private queryResults?: StartupCompletion; private readonly startupQueries = new Subject<StartupCompletion>(); get $startupQueries() { return interval(100) .pipe( filter(() => !!this.queryResults), map(() => this.queryResults as StartupCompletion), take(1) ); } refreshData() { this.initCalled = false; this.initQueries(); } initQueries() { if (this.initCalled) return; this.initCalled = true; // Execute queries // ... this.startupQueries.next(data) } }Este componente ejecuta la consulta inicial y luego, 3 segundos después (para probar), la ejecuta nuevamente.
export class AppComponent { ngOnInit() { this.authService.loggedIn().subscribe(logged => { if(logged) { this.startupQueries.initQueries(); timer(3000).subscribe(() => { console.log('Refresh Queries'); this.startupQueries.refreshData(); }); } } } }Esto debería mostrar el resultado cada vez que se actualice.
export class AnotherComponent { ngOnInit() { this.startup.$startupQueries.subscribe(result => { console.log(result); }) } }Descubrí que usar un BehaviorSubject funciona, parece estar haciendo lo que pretendía.
private queryResults?: StartupCompletion; private readonly startupQueries = new BehaviorSubject<StartupCompletion | undefined>(this.queryResults); $startupQueries = this.startupQueries.asObservable().pipe( filter(() => !!this.queryResults), map(() => this.queryResults as StartupCompletion), );