I am looking to detect a route change in my AppComponent
.
Thereafter I will check the global user token to see if he is logged in. Then I can redirect t
The answers here are correct for router-deprecated. For the latest version of router:
this.router.changes.forEach(() => {
// Do whatever in here
});
or
this.router.changes.subscribe(() => {
// Do whatever in here
});
To see the difference between the two, please check out this SO question.
Edit
For the latest you must do:
this.router.events.subscribe(event: Event => {
// Handle route change
});
In Angular 2 you can subscribe
(Rx event) to a Router instance.
So you can do things like
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Edit (since rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Edit 2 (since 2.0.0)
see also : Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
In Angular 10, you can do something like the following...
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-my-class',
templateUrl: './my-class.component.html',
styleUrls: ['./my-class.component.scss']
})
export class MyClassComponent implements OnInit {
constructor(private router: Router) {}
ngOnInit(): void {
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: NavigationEnd) => {
// code goes here...
});
}
}
@Ludohen answer is great, but in case you don't want to use instanceof
use the following
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
with this way you can check the current event name as a string and if the event occurred you can do what you planned your function to do.
For Angular 7 someone should write like:
this.router.events.subscribe((event: Event) => {})
A detailed example can be as follows:
import { Component } from '@angular/core';
import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
// Show loading indicator
}
if (event instanceof NavigationEnd) {
// Hide loading indicator
}
if (event instanceof NavigationError) {
// Hide loading indicator
// Present error to user
console.log(event.error);
}
});
}
}
The following KIND of works and may do the tricky for you.
// in constructor of your app.ts with router and auth services injected
router.subscribe(path => {
if (!authService.isAuthorised(path)) //whatever your auth service needs
router.navigate(['/Login']);
});
Unfortunately this redirects later in the routing process than I'd like. The onActivate()
of the original target component is called before the redirect.
There is a @CanActivate
decorator you can use on the target component but this is a) not centralised and b) does not benefit from injected services.
It would be great if anyone can suggest a better way of centrally authorising a route before it is committed. I'm sure there must be a better way.
This is my current code (How would I change it to listen to the route change?):
import {Component, View, bootstrap, bind, provide} from 'angular2/angular2';
import {ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';
import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import { Todo } from './components/todo/todo';
import { About } from './components/about/about';
@Component({
selector: 'app'
})
@View({
template: `
<div class="container">
<nav>
<ul>
<li><a [router-link]="['/Home']">Todo</a></li>
<li><a [router-link]="['/About']">About</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
</div>
`,
directives: [RouterOutlet, RouterLink]
})
@RouteConfig([
{ path: '/', redirectTo: '/home' },
{ path: '/home', component: Todo, as: 'Home' },
{ path: '/about', component: About, as: 'About' }
])
class AppComponent {
constructor(location: Location){
location.go('/');
}
}
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'})]);