Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2+: How to access active route outside router-outlet

Tags:

I have an Angular 5 application.

I have the following code in my app component.

I want to hide navbar and topbar for particular routes.

Is it possible to get currently activated route in app.component.ts ? if so, How ?

If not possible, is there any solution to resolve this ( using guards or whatever else ... )?

enter image description here

Also keep in mind that it should be reactive. when i switch to another route sidebar and navbar should show again.

like image 406
Badis Merabet Avatar asked Apr 03 '18 14:04

Badis Merabet


People also ask

Can we pass data in router outlet in Angular?

Angular 7.2. 0 introduced a new way to pass data using State Object while navigating between routed components. The benefit of using a state object is that you can share data between routed components with routeParams without displaying it on the URL segment, unlike queryParams in Angular.

How would you use a router outlet to display a view in Angular?

Router-outlet in Angular works as a placeholder which is used to load the different components dynamically based on the activated component or current route state. Navigation can be done using router-outlet directive and the activated component will take place inside the router-outlet to load its content.

What does the ActivatedRoute interface allows you to access?

ActivatedRoutelink. Provides access to information about a route associated with a component that is loaded in an outlet. Use to traverse the RouterState tree and extract information from nodes.


2 Answers

To get the active route without subscribing to router events, you can simply use a while loop recursively to find the lowest child.

private getActivatedRoute(): ActivatedRoute {
    let route = this.router.routerState.root;
    while (route.firstChild) {
        route = route.firstChild;
    }
    return route;
}
like image 26
asdf Avatar answered Oct 20 '22 00:10

asdf


Try this:

in app.component.ts

import { Component } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';
import { Observable } from 'rxjs/Observable';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
  showSidebar$: Observable<boolean>;
  private defaultShowSidebar = true;

  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
  ) {
    this.showSidebar$ = this.router.events.pipe(
      filter(e => e instanceof NavigationEnd),
      map(() => activatedRoute),
      map(route => {
        while (route.firstChild) {
          route = route.firstChild;
        }
        return route;
      }),
      mergeMap(route => route.data),
      map(data => data.hasOwnProperty('showSidebar') ? data.showSidebar : this.defaultShowSidebar),
    )
  }

app.component.html

<aside *ngIf="showSidebar$ | async">Sidebar here</aside>

<router-outlet></router-outlet>

<a routerLink="/without-sidebar">Without sidebar</a>
<a routerLink="/with-sidebar">With sidebar</a>
<a routerLink="/without-data">Without data.showSidebar</a>

app routes

RouterModule.forRoot([
  { path: 'with-sidebar', component: WithSidebarComponent, data: { showSidebar: true } },
  { path: 'without-sidebar', component: WithoutSidebarComponent, data: { showSidebar: false } },
  { path: 'without-data', component: WithoutDataComponent },
])

You can modify it as you please.

Live demo

like image 51
Tomasz Kula Avatar answered Oct 20 '22 00:10

Tomasz Kula