Hi!
I played around with navigation in Ionic based on this content:
With an Angular Guard I can prevent/enable page activation. Lets say I would like to prevent/enable navigation based on Id, i can choose between the following scenarios:
-
Navigation happens with route parameter
this.router.navigate(['inside/list/details', this.myid]);
Inside canActivate i check if the id is there or not, like this:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const selectedId = route.paramMap.get('id');
console.log(selectedId) // Print out myid
...
}
-
Navigation happens with queryParams
let navigationExtras: NavigationExtras = {
queryParams: {
id: this.myid
},
queryParamsHandling: 'merge'
};
this.router.navigate(['inside/list/details'], navigationExtras);
Inside canActivate i check if the id is there or not, like this:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const selectedId = route.queryParams.id;
console.log(selectedId) // Print out myid
...
}
-
Navigation happens with extras
let navigationExtras: NavigationExtras = {
state: {
id: this.myid
}
};
this.router.navigateByUrl('inside/list/details', navigationExtras);
Inside canActivate i check if the id is there or not, like this:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const currentNavigation = this.router.getCurrentNavigation(); //Requires 'private router: Router' in the constructor
const selectedId = currentNavigation.extras.state.id;
console.log(selectedId) // Print out myId
...
}
However, if i navigate from this page to an another one, and from there i navigate back to the details page using <ion-back-button defaultHref="inside"></ion-back-button>
, the guard will run again.
There is no problem with that in case of route parameter or queryParams but if prevoiusly i used extras, then the guard will fail. In every case the data is there where it should be but if i used NavigationExtras state to transfer the id before, then i can not get it from anywhere.
I’m trying to get the data in a wrong way or backward navigation with ionic-back-button has some issue with extras?
Many thanks in advance!!
Hmm, do you have a repo we could run and inspect?
Quickly forked the original and made the modifications:
Choose any of the three:
Then go to the details-two page
Then go back
You can follow the outcomes in the console.
Hope this helps and thanks again!!
Sorry to bother you, but you got anything regarding the problem?
@mhartington Happy new year
Got anything regarding the problem or should i try to report it on an another platform? It would be important to me but i do not want to bother you with it if you do not have time. Many thanks!!
Short answer, you’re using canActivate
, which will always fire when trying to load/show a component. Use canLoad
instead
Many thanks!!! I can live with that for now 
If you will have time for the long answer I would be curious about it, I assume somebody who is forced to use canActivate (for some reason), should be able to resove it as well.
Sure, long answer is…
canActivate
will fire when ever a route is about to be come “active” this could me forward navigation or back navigation. canActivate
just wants to answer the question "should this route be allowed to be navigated to.
canLoad
is slightly different, instead, it will try determine if a lazy loaded route’s module can loaded at all. Meaning if the module is loaded once, it will only ever run once, since those are cached in memory.
So think of it like this:
canLoad
: I want to control if this whole feature/lazy loaded module should be loaded, including childRoutes declared in it
canActivate
: Doesn’t matter when and where I am, should this navigation be allowed or blocked.
Most of the time, you’ll want canLoad, but if you really need to use or have to use canActivate
, remember that the class for the guard is stateful, so you can make notes in there.
export class DummyGuardService implements CanActivate, CanLoad {
didActivateAlready = false;
canActivate(route: ActivatedRouteSnapshot): boolean {
console.log('has been activated before: ',this.didActivateAlready)
if (!this.didActivateAlready) {
// some sort of logic needed....
this.didActivateAlready = true;
}
return true;
}
}
This way, any setup logic needed will only be done once.
1 Like
Much appreciated, many thanks for your time!! 
1 Like