Búsqueda de sitios web

javascript - Angular rxjs: Retrasar la suscripción hasta que otro Observable emita


Tengo 2 suscripciones: una es una suscripción de mi ActivatedRoute y otra del almacén ngrx.

  ngOnInit() {
    this.menuItems$ = this.store.select('menuItems');
    this.menuItems$.subscribe(data => {
      this.menuItems = data.menuItems;
    });
  }

  ngAfterViewInit() {
    this.fragmentSubscription = this.route.fragment.pipe(
      filter((fragment: string) => typeof fragment === 'string')
    ).subscribe((fragment: string) => {
      setTimeout(() => {
        const element: ElementRef = this.menuItems.find(menuItem => menuItem.link === fragment).element;
        if(element !== undefined) {
          element.nativeElement.scrollIntoView({ behavior: "smooth", block: "start", inline: "center" });
        }
      });
    });
  }

Dado que mi suscripción a ActivatedRoute (fragment) depende de los datos de suscripción de mi store, quiero retrasar mi suscripción a ActivatedRoute (fragment) hasta que mi Store se suscriba por primera vez

¿Existe algún operador de rxjs para esto?

Gracias

Respuesta #1

Basado en tu comentario...

Si la primera vez que la Tienda emite ha terminado, ya no quiero esperar por ello cuando ActivatedRoute se suscribe

Estás buscando combineLatest, que...

Cuando cualquier observable emite un valor, emite el último valor emitido de cada uno.

Así que sugiero lo siguiente:

import { Subscription, combineLatest } from 'rxjs';

// ...

mySubscription: Subscription;

ngOnInit() {
  this.mySubscription = combineLatest(
    this.store.select('menuItems'),
    this.route.fragment.pipe(
      filter((fragment: string) => typeof fragment === 'string')
    )
  // DON'T USE ANY, type your data...!
  ).subscribe((data: [any, any]) => {
    this.menuItems = data[0];
    const fragment = data[1]
    // do your thing...
  })
}

ngOnDestroy() {
  this.mySubscription.unsubscribe();
}

Respuesta #2

No obtengas tus datos en init desde la tienda si es posible. Obténlos desde un resolvedor.

Por supuesto, puedes obtenerlos de la tienda en el resolvedor y luego acceder a ellos en la función init como un valor.

Busca más información aquí https://angular.io/api/router/Resolve