0

Using the router events I can see the navigation changes and the updated URL. But how do I get the actual router state (data, resolves, parameters, etc) from the URL. I tried using the ActivatedRoute but this is only initialized once the component is initialized.

Current code:

@Component({...})
export class SecundaryMenuComponent implements OnInit, OnDestroy {
  private titleSubject$: BehaviorSubject<string> = new BehaviorSubject<string>('');
  public title$: Observable<string> = this.titleSubject$.asObservable();

  private navSubscription: Subscription;

  constructor(private router: Router, private activeRoute: ActivatedRoute) {
    this.navSubscription = this.router.events.subscribe((event: NavigationEvent) => {
      this.handleRoutingEvent(event);
    });
  }

  ngOnInit(): void {}

  ngOnDestroy(): void {
    this.navSubscription.unsubscribe();
  }

  handleRoutingEvent(event: NavigationEvent) {
    if (event instanceof NavigationEnd) {
      this.titleSubject$.next(event.urlAfterRedirects);
    }
  }
}

So how can I access the active router state in the handleRoutingEvent function?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Kees de Bruin
  • 175
  • 2
  • 16

2 Answers2

0

May be you try this:

@Component({templateUrl:'template.html'})
class MyComponent {
  constructor(router: Router) {
    const state: RouterState = router.routerState;
    const root: ActivatedRoute = state.root;
    const child = root.firstChild;
    const id: Observable<string> = child.params.map(p => p.id);
    //...
  }
}
Rafa
  • 467
  • 4
  • 18
  • This works only a single time and not when routes change. This is a header component that needs to update e.g. a title and some other elements such as a tab bar. – Kees de Bruin Feb 25 '22 at 09:07
  • Then add `router.routeReuseStrategy.shouldReuseRoute = () => false;` – tony Feb 25 '22 at 09:15
0

After more searching I found this and changed my code to the following:

@Component({...})
export class SecundaryMenuComponent implements OnInit, OnDestroy {
  private titleSubject$: BehaviorSubject<string> = new BehaviorSubject<string>('');
  public title$: Observable<string> = this.titleSubject$.asObservable();

  private routeUrl$: Observable<UrlSegment[]>;
  private routeUrlSubscription: Subscription;

  constructor(private router: Router, private route: ActivatedRoute) {
    this.routeUrl$ = this.router.events.pipe(
      filter((event) => event instanceof NavigationEnd),
      switchMap(() => {
        const url = this.route.firstChild?.url;
        return url || of();
      })
    );

    this.routeUrlSubscription = this.routeUrl$.subscribe((url) => this.handleRouteUrl(url));
  }

  ngOnInit(): void {}

  ngOnDestroy(): void {
    this.routeUrlSubscription.unsubscribe();
  }

  handleRouteUrl(url: UrlSegment[]) {
    let routeUrl = '/' + url.join('/');
    this.titleSubject$.next(routeUrl);
  }
}

Now I get the proper title based on the actual router data instead of the event URL. The same principle can also be used to get the parameters, data, etc.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Kees de Bruin
  • 175
  • 2
  • 16
  • I have moved your answer from the question to this answer. Questions should not contain the answer to that question. Even if you solved your own question, you should post it in an answer, not as an edit to your question. – Mark Rotteveel Feb 26 '22 at 08:53