Ionic/Angular Routing Bug/Intended?

I’m not sure whether this is intended or is a bug:

(1) http://localhost:8100/home navigates to
(2) http://localhost:8100/posts navigates to
(3) http://localhost:8100/posts/post-detail/123 navigates to
(4) http://localhost:8100/users navigates to
(5) http://localhost:8100/users/user-detail/456 navigates to
(6) http://localhost:8100/posts/post-detail/123 — clicking the BACK BUTTON here goes back to (2)

Clicking the back button on (6) pops off (3)(4)(5) because the router knows that the page has been initialized before.

My setup:

npx ionic --version
5.2.1

"@ionic/angular": {
      "version": "4.7.0",
      "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-4.7.0.tgz",
      "integrity": "sha512-m4lMAm1wZb+oBAg4TBaI7DImDs8FLxG+z2dbqyRh1KGRbd1SExvyDq0Rleebl/AJBwiYHfCWltye1MEffUZBfA==",
      "requires": {
        "@ionic/core": "4.7.0",
        "tslib": "^1.9.3"
      }
    },

What’s the template look like for the post-detail page?

Hi @max ! The template associated with the back button looks like this:

    <ion-buttons slot="start">
      <ion-back-button *ngIf="canGoBack" defaultHref="/login"></ion-back-button>
      <ion-menu-button *ngIf="hasMenu" menu="nav"></ion-menu-button>
      <ion-button *ngFor="let sb of startButtons" (click)="onStartButton(sb.clickListener)">
        <ion-icon name="{{ sb.iconName }}"></ion-icon>
      </ion-button>
    </ion-buttons>

My entire application traverses either via [routerLink] in HTML or this.router.navigate([]) in the component logic.

For my back button logic, the entire app uses ion-back-button.

Hi @max Do you or anyone else have suggestions/ideas as to what/why this is happening? And whether this is intended?

Sorry I’m struggling to figure out what’s going on, I’d need to see more code. If you can share anything else that would be hugely helpful.

I will simplify my code to make it easier to digest :smiley:

My routing looks like the below:

// app-routing.module.ts
const routes: Routes = [
  {
    path: 'posts',
    loadChildren: './posts/posts.module#PostPageModule',
    canLoad: [AuthGuard]
  },
  {
    path: 'users',
    loadChildren: './users/users.module#UserPageModule',
    canLoad: [AuthGuard]
  },
...
// posts.module.ts
const routes: Routes = [
  {
    path: '',
    component: PostPage
  },
  {
    path: 'post-detail/:postId',
    loadChildren: './post-detail/post-detail.module#PostDetailPageModule'
  },
]
// users.module.ts
const routes: Routes = [
  {
    path: '',
    component: UserPage
  },
  {
    path: 'user-detail/:userId',
    loadChildren: './user-detail/user-detail.module#UserDetailPageModule'
  },
]

To traverse from http://localhost:8100/home to http://localhost:8100/posts:

<!-- home.page.html -->
<ion-button [routerLink]="/posts"></ion-button>

To traverse from http://localhost:8100/posts to http://localhost:8100/posts/post-detail/123

<!-- posts.page.html -->
<ion-item (click)="navigateToDetail(post)"></ion-item>
// posts.page.ts
public navigateToDetail(post: Post): Promise<void> {
  this.router.navigate(['/posts/post-detail', post.postId]);
}

To traverse from http://localhost:8100/posts/post-detail/123 to http://localhost:8100/users

<!-- post-detail.page.html -->
<ion-button (click)="onNavigateToUsers()"></ion-button>
// post-detail.page.ts
public navigateToUsers(): Promise<void> {
  this.router.navigate(['/users']);
}

To traverse from http://localhost:8100/users to http://localhost:8100/users/user-detail/456

<!-- users.page.html -->
<ion-item (click)="navigateToDetail(user)"></ion-item>
// users.page.ts
public navigateToDetail(user: User): Promise<void> {
  this.router.navigate(['/users/user-detail', user.userId]);
}

Traverse from http://localhost:8100/users/user-detail/456 to http://localhost:8100/posts/post-detail/123

<!-- user-detail.page.html -->
<ion-item (click)="navigateToDetail(post)"></ion-item>
// user-detail.page.ts
public navigateToDetail(post: Post): Promise<void> {
  this.router.navigate(['/posts/post-detail', post.postId]);
}

Once I am on http://localhost:8100/posts/post-detail/123 and press the back button

<!-- post-detail.page.html -->
<ion-back-button defaultHref="/home"></ion-back-button>

I am brought back to http://localhost:8100/posts (incorrect!)

I expect to be brought back to http://localhost:8100/users/user-detail/456 because that was my previous page.

@max Please let me know if you need any additional information.

Are there any tabs in use anywhere in sight here?

@rapropos If you are referencing Ionic Tabs, I am not using any in my application.

I am, however, using Ionic Menu in my application.

For steps 1-6, I am purely using the routerLink in HTML and the Angular Router in the component logic. I am not navigating using the menu in this specific scenario.

1 Like

Does anyone else know why am I experiencing this? Is this intended?

Hey @wenindoubt so I did a little debugging and was able to reproduce. What’s happening is Ionic Angular caches pages based on URL matches, so the history stack is sliced once you go forward to the post-detail URL (it’s essentially going back to that cached page) since you’re going to the same route.

A workaround would be to somehow go to a unique URL again. That could be by adding a random number in the path or dealing with the fact that this will only happen when going back to a post-detail with the same id as used before. So, if you want to /posts/post-detail/987 you should see the back button working correctly.

Hey @max, thank you so much! While I believe adding a unique identifier to the pages could be a solution, it could open up other issues in my app (such as an infinitely navigating forward).

What do you think of hijacking the back button via:

import { Location } from '@angular/common';
import { NavController } from '@ionic/angular';

...

constructor(private location: Location, private navCtrl: NavController) {}

...

this.navCtrl.setDirection('back', true, 'back');
this.location.back();

Is the NavController set to be deprecated any time in the near future and I should avoid using that?

No plans to deprecate that, it’s used under the hood for all the navigation features. If it works, go for it!

1 Like