I\'ve created a CanDeactivate guard which returns an observable and it\'s applied to a component which is loaded in a inner nested router-outlet. Should this guard be called whe
Damn, bug...Note to self: next time, check the issues board first
https://github.com/angular/angular/issues/12851#event-880719778
i have found this solution, instead of creating a candeactivate guard for every component, you will create one guard service and add a candeactivate method to every component you want to add this option, so first you have to add this service file "deactivate-guard.service.ts":
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable()
export class DeactivateGuardService implements CanDeactivate<CanComponentDeactivate>{
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
then you have to provide in the app module:
providers: [
DeactivateGuardService
]
now in the component you want to protect, add the function:
export class ExampleComponent {
loading: boolean = false;
//some behaviour that change the loading value
canDeactivate() {
console.log('i am navigating away');
if (this.loading) {
console.log('no, you wont navigate anywhere');
return false;
}
console.log('you are going away, goodby');
return true;
}
}
you can see that the variable loading is local to the component. the final step is to add the directive to the component in the routing module:
{
path: 'example',
canDeactivate: [DeactivateGuardService],
component: ExampleComponent
}
and thats it, i hope this was helpfull, goodluck.