nativescript-angular
nativescript-angular copied to clipboard
NgOnDestroy - ClearHistory - Custom NSRouteReuseStrategy
Bug Short Version:
When using a custom NSRouteReuseStrategy navigating with clearHistory does not call ngOnDestroy. Without custom NSRouteReuseStrategy ngOnDestroy is called as expected.
Bug in more Detail:
Custom NSRouteReuseStrategy Imagine we have 3 Pages: P1, P2 and P3 We Start with P1 then navigate to P2 and then to P3
- P1 ngOnInit() is called
- P2 ngOnInit() is called
- P3 ngOnInit() is called
Then navigate to P1 with clearHistory this.nav.navigate(["P1"], { clearHistory: true });
ngOnDestroy is NOT CALLED for P3, P2 and P1.
Without custom NSRouteReuseStrategy We Start with P1 then navigate to P2 and then to P3
- P1 ngOnInit() is called
- P2 ngOnInit() is called
- P3 ngOnInit() is called
Then navigate to P1 with clearHistory this.nav.navigate(["P1"], { clearHistory: true });
ngOnDestroy is called for P3, P2 and P1 (as expected).
To Reproduce I have created a Playground: https://play.nativescript.org/?template=play-ng&id=1TvIZG&v=3
- Launch it and then press the NEXT button a few times.
- Press the P1 [CLEAR] HISTORY button (App will navigate to P1 with clearHistory: true - See *Info)
- Take a look at the logs (Press TOGGLE LOGS - top right corner)
- Hide the logs again (Press TOGGLE LOGS - top right corner)
- Press P1 [FORCE CLEAR] HISTORY (App will navigate to P1 CustomRouteReuseStrategy will call clearCache See *Info)
- Take a look at the logs - NgOnDestroy() is called
*Info:
Step 2) P1 [CLEAR] HISTORY just calls this.nav.navigate(["P1"], { clearHistory: true });
Step 5) P1 [FORCE CLEAR] HISTORY calls this.nav.navigate(["P1"], { queryParams: { forceClearHistory: true } }); The CustomRouteReuseStrategy checks the queryParams and if forceClearHistory is true it calls this.clearCache(current.outlet);
PS: You can uncomment / comment the following lines in app.module.ts to see what I mean
{
provide: RouteReuseStrategy,
useClass: CustomRouteReuseStrategy
}
Expected behavior
Maybe it is the expected behavior but this is what I was expecting:
If I navigate with clearHistory: true this.nav.navigate(["P1"], { clearHistory: true }); I expect that NgOnDestroy() is called on all pages in the history stack.
Noticed the same issue, the following config served as a workaround for me in app.module.ts.
Not sure if a bug or documentation issues. I think it is because PageRouterOutlet injects NSRouteReuseStrategy rather than RouteReuseStrategy type.
providers: [ CustomRouteReuseStrategy,
{
provide: RouteReuseStrategy,
useExisting: CustomRouteReuseStrategy
}
,{
provide: NSRouteReuseStrategy ,
useExisting: CustomRouteReuseStrategy
}]
@vakrilov Ran into this today as well - is this a regression in the latest? Don't believe it always worked this way?
@NathanWalker definitely a regression. I've just noticed this in our live apps that used to work properly on NS7.
EDIT: I have to clarify that this is happening to me even WITHOUT using a custom strategy
EDIT2: The workaround does not seem to be working for me. The cache is being cleared, but ngOnDestroy is not being called, even when explicitly returning false from shouldReuseRoute
As a temporary workaround that works for me, I am using this:
@HostListener('unloaded')
cleanup() {
if (!this.routerExtensions.canGoBackToPreviousPage()) {
this.ngOnDestroy()
}
}
You could also do the same with Page.navigatedFrom
EDIT: A caveat this workaround won't work for the following flow: Page A -> Page B -> Page C -> (navigated with clearHistory) Page A
Page A's ngOnDestroy won't be called, where previously C->A clearHistory navigation took care of that
EDIT2:
When the application is put to the background (switching away) unloaded is called. So you might want to check for that before calling destroy.