I need to hide certain components from my main home page like the navbar and footer when I'm logged in to my admin panel. My admin components are lazy-loaded based on an admin module when called. The necessary components are getting hidden as expected when on admin view if the routes are not dynamic i.e like /admin/login
, /admin/dashboard
etc. But the problem starts if the routes are dynamic like /admin/category/:categoryId
or /admin/user/:userId
and in these routes the necessary components like navbar and footer doesn't hide itself. I'm getting the dynamic ids for the routes using ActivatedRoute
in the necessary components. Below is the method I'm using on my main page to read the application routes and show/hide components accordingly.
Main.ts
import { Router, NavigationEnd } from '@angular/router';
public url: any;
constructor(private router: Router) {
this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
this.url = event.url;
}
})
}
Main.html
<div class="main__container">
<app-navbar
*ngIf="url !== '/admin' && url !== '/admin/dashboard' && url !== '/admin/post-article' && url !== '/admin/video' && url !== '/admin/login' && url !== '/admin/sign-up' && url !== '/admin/category/:categoryId'">
</app-navbar>
<app-footer
*ngIf="url !== '/admin' && url !== '/admin/dashboard' && url !== '/admin/category/:categoryId' && url !== '/admin/post-article' && url !== '/admin/video' && url !== '/admin/login' && url !== '/admin/sign-up'">
</app-footer>
</div>
What you need here is to define regular expressions and test against those.
Or maybe it's enough for you to check the string#includes(string)
function. I would also suggest to use a more reactive (rxjs like) approach.
On my template I would have:
<div class="main__container">
<app-navbar *ngIf="canShowNavBar$ | async">
</app-navbar>
<app-footer *ngIf="canShowFooter$ | async">
</app-footer>
</div>
Where on the typescript file I would have:
export class YourComponent implements OnInit {
canShowNavBar$: Observable<boolean>;
canShowFooter$: Observable<boolean>;
navigationEvents$: Observable<NavigationEnd>;
constructor(private router: Router){}
ngOnInit() {
// Like this we define the stream of the NavigationEnd events
this.navigationEvents$ = this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
// This one is not really needed but we're giving some hints to the typescript compiler
map(event => event as NavigationEnd)
);
// Here we define the stream of booleans that determine whether to show the component or not on your template.
this.canShowNavBar$ = this.navigationEvents$.pipe(
map(event => this.shouldShowNavBar(event.url))
);
// Because actually you check for the same conditions
this.canShowFooter$ = this.canShowNavBar$;
}
shouldShowNavBar(url: string): boolean {
// And here you should test against regular expressions:
switch(true) {
case /\/admin\/dashboard/.test(url):
case /\/admin\/category/.test(url):
// More cases where you should show the navBar
return true;
default: return false;
}
}
}
You can read more about Regular Expressions on JavaScript here
Another approach of implementing the shouldShowNavBar
would be using some array predicates like some
: Like so:
shouldShowNavBar(url: string): boolean {
const conditions = [
!url.startsWith('/admin/dashboard'),
!url.includes('/admin/category'),
// More conditions?
];
return conditions.some(isTrue => isTrue);
}
<div class="main__container">
<app-navbar *ngIf="shouldDisplayNavBar(url)">
</app-navbar>
<app-footer *ngIf="shouldDisplayNavBar(url)">
</app-footer>
</div>
shouldShowNavBar(url: string): boolean {
if(!url) {
return false;
}
const conditions = [
!url.startsWith('/admin/dashboard'),
!url.includes('/admin/category'),
// More conditions?
];
return conditions.some(isTrue => isTrue);
}