3

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

3
  • You can try using forkJoin learnrxjs.io/operators/combination/forkjoin.html Commented Oct 30, 2019 at 16:17
  • @penleychan Looks good but I want to do that only once and not always. If the first time when the Store emits has completed, I no longer want to wait for it when the ActivatedRoute subscribes Commented Oct 30, 2019 at 16:26
  • better pass the menueItems list from where you are navigating to this page via navigationExtras in router.navigate method Commented Oct 30, 2019 at 16:40

2 Answers 2

2

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(); } 
Sign up to request clarification or add additional context in comments.

2 Comments

Works perfect and exectly what I needed. Thank you.
You are very welcome, glad to hear it was suitable for you! :)
0

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

1 Comment

Great approach, but this is not works in this case as I am retreiving the data of the Store from the child components = after ngOnInit (as they are loaded only after the parent component is activated). But thank you!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.