7

I want to check the active child route in parent component but I don't know how to get this. I am trying to use ActivatedRoute but not able to get it.

I have tried both of the answers from Angular2 (rc4) - Check active child route in parent component:

  1. I have tried the accepted answer:

    constructor(
        private router:Router,
        private route: ActivatedRoute
     ) {
         var state = this.router.routerState
         var children = state.children(this.route)
     }
    

    With this I am getting this error:

    Property 'children' does not exist on type 'RouterState'
    
  2. I have tried with this one as well:

    this.router.events.filter(evt => evt instanceof NavigationEnd)
       .map(evt => evt.url)
       .subscribe(url => console.log(url));
    

    but getting these error with this one:

    property 'url' does not exist on type 'Event'
    property 'url' does not exist on type 'RouteConfigLoadStart'`
    

Any idea?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Aakriti.G
  • 656
  • 1
  • 10
  • 26

3 Answers3

11

I would say Angular (via TypeScript) is just being very type strict. You can work around it... Here is a brief example of just getting the name/path of the immediate child route.

this.router.events.filter(evt => evt instanceof NavigationEnd)
        .subscribe((event) => {
            console.log(event['url']);
            console.log(this.route.firstChild.routeConfig.path);
        });
Steve Sanders
  • 8,444
  • 2
  • 30
  • 32
GeorgeFrick
  • 154
  • 2
  • 7
5

There's an overload to RxJS filter that makes it into a typeguard. The output then becomes an actual NavigationError object instead of just being a RouterEvent.

   this.router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd));

Anything after this in your pipe(...) will be of type NavigationEnd and will have url on it.

I recommend creating a helper service called something like RouterEventsService and creating common observables on it that you can use from anywhere.

Just a simple service like this:

@Injectable({ providedIn: 'root' })
export class RouterEventsService
{
    constructor(private router: Router) {}

    // navigation lifetime
    navigationStart$ = this.router.events.pipe(filter((e): e is NavigationStart => e instanceof NavigationStart));
    navigationEnd$ = this.router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd));

    // you can add clever things to it as needed
    navigationDurationMs$ = this.navigationStart$.pipe(switchMap(() => 
    {
        const startTime = new Date().getTime();
        return this.navigationEnd$.pipe(take(1), map(() => new Date().getTime() - startTime));
    }), 
    shareReplay(1));
}
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • 1
    all you need is `filter((event: NavigationEnd) => event instanceof NavigationEnd),` to take advantage of the typeguard this answer mentions – runderworld Jan 07 '21 at 22:36
0

Dont forget to import rxjs

import 'rxjs/add/operator/filter';