Ron Rofe
Ron Rofe

Reputation: 796

Angular rxjs: Delay subscription till other Observable emits

I have 2 Subscription - one is a subscription of my ActivatedRoute and another from ngrx Store.

  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" });
        }
      });
    });
  }

As my ActivatedRoute (fragment) subscription depends on my store subscription data, I want to delay my ActivatedRoute (fragment) subscription till my Store is subscribed for the first time

Is there any rxjs operator for this?

Tnx

Upvotes: 3

Views: 1160

Answers (2)

AVJT82
AVJT82

Reputation: 73337

Based on your comment...

If the first time when the Store emits has completed, I no longer want to wait for it when the ActivatedRoute subscribes

You are looking for combineLatest, which...

When any observable emits a value, emit the last emitted value from each.

So I suggest the following:

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();
}

Upvotes: 2

Athanasios Kataras
Athanasios Kataras

Reputation: 26342

Don't get your data in init from the store if possible. Get them from a resolver.

You can ofcourse get them from the store in the resolver and then access them in the init function as a value.

Look for more information here https://angular.io/api/router/Resolve

Upvotes: 0

Related Questions