ionic-framework: [4.0.0.beta-17] ActivatedRoute.queryParams break after navigation
Bug Report
Ionic version: 4.0.0.beta-17 and 4.0.0.beta-18
Current behavior: Subscriptions on ActivatedRoute.queryParams do not fire after navigating away from and returning to that page. This is particullary problematic for base pages of tabs that are cached. The problem does not occur on sub-pages because they are re-initialized i.e. onInit fires again and again (e.g. on speaker-detail in ionic-conference app).
Expected behavior: Navigation should not interfere with the queryParams subscription.
Steps to reproduce:
- Clone ionic-conference-app
- Add code below
- Test with “Test” button on speakers list. Observe console log of queryParams. Navigate to speaker detail and back. Try “Test” button again and observe no console output.
- Test same with Test button speaker detail page. Navigate from base to detail and back and to detail again - logs are fired.
Related code:
speaker-list.html
<ion-content class="outer-content">
<!-- TEST BUTTON -->
<ion-button (click)="test()">Test</ion-button>
<ion-list>
...
in speaker-list.ts modify
...
export class SpeakerListPage implements OnInit {
speakers: any[] = [];
constructor(
public actionSheetCtrl: ActionSheetController,
public confData: ConferenceData,
public inAppBrowser: InAppBrowser,
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
console.log('Init');
this.route.queryParams.subscribe(test => console.log(test));
}
test() {
this.router.navigate(['./'], { queryParams: { test: Math.random() }, relativeTo: this.route });
}
...
Ionic info:
Ionic:
ionic (Ionic CLI) : 4.5.0 (C:\Users\Ferdinand\AppData\Roaming\npm\node_modules\ionic)
Ionic Framework : @ionic/angular 4.0.0-beta.17
@angular-devkit/build-angular : 0.10.7
@angular-devkit/schematics : 7.1.3
@angular/cli : 7.1.3
@ionic/angular-toolkit : 1.2.0
Cordova:
cordova (Cordova CLI) : 8.1.2 (cordova-lib@8.1.1)
Cordova Platforms : android 7.1.4
Cordova Plugins : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.2.5, (and 8 other plugins)
System:
NodeJS : v10.11.0 (C:\Program Files\nodejs\node.exe)
npm : 6.4.1
OS : Windows 10
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 13
- Comments: 19 (7 by maintainers)
Commits related to this issue
- fix(angular): support relative router links Closes #17888, closes #16534, closes #16736, closes #16954 — committed to kiku-jw/ionic by daem0ndev 5 years ago
I can confirm this issue as this was quite a blocker for us, the problem is that the OutletInjector class inside ion-router-outlet only provides the correct ActivatedRoute during initial component initialization, but this is not the correct ActivatedRoute when re-activating a component thats already in the ion-router-outlet stack. The fact of the matter is, there is no easy way to correct this issue from Ionic’s side because you cant change the injected activated route after the fact. In other words, the activated route thats injected on a component is only correct if the component is being created by the factory, NOT if we are reactivating a component thats already created, and navigating BACK to that component is actually a whole new navigation and therefor new ActivatedRoute object.
I implemented a very crude workaround to this issue because we have a tight deadline to release our app. The main gist of the solution is that I created a service that always maintains the current activated route as well as the component that is activated and exposes this via an observable, and then on my page components I use this service to get the latest (and correct) instance of ActivatedRoute as it changes over time (i.e. when navigating BACK to a component on the stack) and then you can correctly switchMap over to the queryParamMap on that new ActivatedRoute.
Hey everyone. We just merged in #17888 which fixes this. Thanks for all your patience here 😄
This issue seems to be resolved with the service in https://github.com/ionic-team/ionic/issues/15959#issuecomment-439624872, but I have used a slightly approach to solve it with absolute link, and I’d like to share it with everyone here. This approach is similar to what https://github.com/ionic-team/ionic/issues/15959#issuecomment-431525775 suggested. I’d like to provide more detail to it.
My problem: I have a page which navigates to another page via a path relative to the first page. When I navigate back to the first page, subscription to (ActivatedRoute) route.queryParams or route.params didn’t trigger.
My workaround: I navigate to the second page via (NavController) navCtrl.navigateRoot(), so that the first page is always destroyed in the stack. When I visit it back from the second page, ngOnInit and the subscription inside it are always triggered.
However, I do hope that the Ionic team can resolve this as soon as possible.
Are there any thoughts from the team on when this might be fixed? Prior to Final? Seems pretty important for using the correct navigation parameters if the recommendation and default is to use cached Pages.
Okay, we found a viable work-around.
If we put the the queryParams subscription into a seperate service
it will react to all param changes as expected. In particular, in the example above “when you use “test” params on the base page, navigate to a child page, put a link there back to the base page with another test=Math.Random()” - the queryParams correctly fires. It does not fire, if the subscription is done in the ngOnInit which is the core problem that I do not understand.
So summa sumarum: queryParams subscriptions in angular components are getting corrupted while queryParams subscriptions outside of these components work as intended.
EDIT: I guess the injected ActivatedRoute in the component stays somewhere open, the subscriptions will also be open, but upon navigating away and back, this injected route: ActivatedRoute is not used again, but instead a new ActivatedRoute is created and put into its place (I don’t know the deep details of injection of angular).