Reputation: 3566
I'm trying to run a function whenever current route is changed. For example, if we are currently on "..../user/user-details", where user-details is a separate component. I want to execute a method whenever the route is changed (shouldn't matter if route changes from the UI or directly from the URL). I did something in the user-details component:
constructor(private router: Router) {
router.events.subscribe(() => {
console.log('Route changed');
});
}
But the issue with this approach is, it runs on every route change (whether or not we are navigating to or from user-details page). So this is subscribing to app wide routes. I just want it to run whenever we are navigating away from user-details component. Is their a way to do that?
Upvotes: 6
Views: 5633
Reputation: 14221
If you want to just run code when leaving the user-details component then you need to create a CanDeactivate Guard on the route.
Setup the guard so that the UserDetailsComponent
implments a interface with a method to call before the route gets deactivated. Then register the CanDeactivate
Guard on the route and inside the guard call the method on the route.
interface BeforeUnload {
beforeunload(): Observable<boolean>|Promise<boolean>|boolean;
}
@Component({ /* ... */})
class UserDetailsComponent implements BeforeUnload {
beforeUnload() {
/* ... custom code ... */
return true;
}
}
@Injectable()
class CanDeactivateComponent implements CanDeactivate<T extends BeforeUnload> {
constructor() {}
canDeactivate(
component: T,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
return component.beforeUnload();
}
}
@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'user/user-details',
component: UserDetailsComponent,
canDeactivate: [CanDeactivateComponent]
}
])
],
providers: [CanDeactivateComponent]
})
class AppModule {}
In this example I set it up so that the route won't leave until the method on the component returns a response but you could immediately return true depending on if beforeUnload
is synchronous or not.
Upvotes: 10