I have found an alternative to add a guard dynamically to any route from any component or sub-component (which is pretty useful).
For example, you can create your own guard which will prevent you from an unexpected window closing following this link.
Taking this example into account, let's say that the guard is named : "DownloadCenterGuard". Its purpose is to prevent your browser from closing if a download is currently running.
But as an Angular developer, the actual problem is that your DownloadCenterComponent is a deep sub-component which has no knowledge of which main component it is contained in (and you don't want to add the guard manually into all of your routes).
So the real question is : How the hell we can do that in Angular?
(It works pretty well with Angular 12 and below, to confirm with future versions)
From your sub-component (anywhere into your app), inject the ActivatedRoute into the constructor:
@Component(...)
export class DownloadCenterComponent implements OnDestroy {
constructor(
private _activatedRoute: ActivatedRoute
) {
// You could do the same for the "canActivate" property.
this._activatedRoute.routeConfig.canDeactivate = [
...this._activatedRoute.routeConfig.canDeactivate,
DownloadCenterGuard
];
}
ngOnDestroy() {
// Remove the dynamically added guard at component destroying.
this._activatedRoute.routeConfig.canDeactivate = [
...this._activatedRoute.routeConfig.canDeactivate.filter(guard => guard !== DownloadCenterGuard)
]
}
}
And tadaaam, this is not documented anywhere and it could be unsupported by the Angular team at any time. So use this as less as possible, only if you have no other choice (in my opinion).