The issue persists with Ionic failing to properly clean up pages upon exiting them

My introduction to Ionic (TypeScript + Angular) came out of necessity at work, as I had never worked on mobile development before. This is a whole new experience for me.

I'm currently facing an issue that has me completely stumped. Let me walk you through the scenarios:

Scenario 1

  1. UserA logs in with their credentials
  2. UserA is directed to their profile page after logging in
  3. UserA logs out

Scenario 2

  1. UserB logs in with their credentials
  2. UserB is redirected to the profile page after logging in (but sees UserA's profile information)

Considerations

I am using @ionic/storage to manage sessions and it doesn't seem to be a storage-related problem. After logging out, I checked await session.get('user') which returned undefined. Upon logging back in, await session.get('user') displayed the correct user (the one who just logged in).

What Could Be Going Wrong?

I suspect that Ionic is caching the page when a new user logs in, preventing the constructor and ngOnInit methods from being called again. As a result, the variables retain old user data, leading to incorrect information being displayed.

This seems like the root cause because the issue doesn't occur consistently. Sometimes everything renders correctly initially, but I'm unsure how to resolve this :/

Questions

Has anyone encountered this issue before? What steps did you take to address it?

Is there a way to instruct Ionic not to cache the page?

Can the previous content be forcibly destroyed after a router.navigate() to another page?

Answer №1

When using Ionic, pages are not destroyed by default - they are kept in the DOM to allow for navigation using the back and forward buttons. While vanilla Angular routing allows you to control this behavior with RouteReuseStrategy, ion-router-outlet does not offer the same flexibility. Instead, ion-router-outlet uses a stack to store navigation history and only triggers Ionic lifecycle hooks after a component is created. If you want to clear this stack, you can use navigateRoot() or switch to Angular's router-outlet and router.

In my opinion, this is a notable flaw that is not well-documented. There are many situations where keeping a rendered component in the DOM indefinitely may not be ideal and could potentially lead to significant performance issues.

Answer №2

Encountering a similar problem with Ionic 4 Angular 8, I managed to resolve it by implementing the use of { replaceUrl: true } upon logout button click. Here's an example:

logout() {
    ...
    this.router.navigate(["login"], { replaceUrl: true });
}

Answer №3

When using Ionic, you may encounter situations where pages are kept in the DOM for transition and state purposes. To address this issue, Ionic provides lifecycle methods that allow you to reset the page's state when it is reentered. The IonViewWillEnter method is triggered every time the user navigates to the page, regardless of whether it is already in the DOM or not. For more information on how to use these events, please refer to the documentation: https://ionicframework.com/docs/angular/lifecycle

Answer №4

If you substitute

<ion-router-outlet></ion-router-outlet>
with
<router-outlet></router-outlet>
, the lifecycle hooks of Angular will be activated, allowing you to meet your requirements more easily. However, this approach may not be suitable for an Ionic project.

Alternatively, you can include a router event listener in the constructor and handle further implementation to a certain extent.

For example:

this.router.events.subscribe((event : NavigationEnd) => {
  ...
})

Second technique :

In Ionic, modules are referred to as "Pages." To create pages/modules, use ionic generate page pageName. This way, all Ionic lifecycle hooks like ionViewWillEnter, ionViewDidLeave, etc., will function properly. For the main page, you can create a layout page (dashboard, other modules) and an auth page for login/logout/forgot password, etc.

Simply copy/paste your code from ngOnInit to ionViewWillEnter to ensure it works correctly.

Note: Some Ionic Components' lifecycle hooks may not work as expected, so it is advisable to make maximum use of Pages.

Answer №5

Dealing with a frustrating cache issue on my page.ts where I needed to continuously check if the user was logged in or out to determine whether to display their information or not using a boolean condition, resulting in constantly refreshing the page.

At times, the webpage would show an outdated cached view and prevent me from seeing the logs on my checker function.

The solution that worked for me was implementing ionViewDidLeave() along with a subject.

I am currently utilizing angular 12 & ionic 5.

Here is an excerpt of the problematic page code:

isLogged: boolean;
private unsubscribe = new Subject<void>();

ionViewDidLeave() {
    console.log('Destroyed')
    this.unsubscribe.next()
    this.unsubscribe.complete();
}

ionViewWillEnter() {
    this.setIsLogged();
}

setIsLogged(): void {
   this._userDataService.getUser().pipe(
     takeUntil(this.unsubscribe)
   ).subscribe(
     (user) => {
      this.isLogged = true;
     },
     error => {
      this.isLogged = false;
     });
}

Hopefully, this solution can assist someone else experiencing similar issues :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the emission of Vue 3 with the Options API through typing

Is there a way to declare emits in Vue 3 Options API similar to the Composition API approach? Based on the Composition API documentation: (docs) <script setup lang="ts"> // type-based const emit = defineEmits<{ (e: 'change', ...

Guide to implementing basic authentication within an HTTP request in Angular 4

I'm new to this and I only have experience with the http post method. I need to send the username and password as base authentication for every API request. onSubmit = function(userdata){ this.tokenkey = localStorage.getItem('logintoken&apos ...

Experience the magic of Angular combined with the versatile ng-image-slider; displaying a single image at a

I want to customize my ng-image-slider in my app so that only one image is displayed at a time, while also ensuring that it remains responsive. Besides adjusting the "imageSize" input and manipulating the width/height of the images, what other options do I ...

Issue with React select dropdown not properly updating selected value

My website has a form with the default value of ethExperienceLevel set to "BEGINNER". I have a function that is supposed to update the selected state when switching between options in a dropdown list, triggered by an onChange handler. However, I noticed ...

Sorting data in an Angular JavaScript table by column filters for a combined outcome

I currently have an Angular ngx-datatable that lacks support for filtering by column. My goal is to implement an input filter for each column (which can be strings, multiple choices, etc.) and then merge all these individual filters into a single one. This ...

What is the best way to address dynamic meta tags in Angular server-side rendering (SSR

My Angular application uses server side rendering, and I am dynamically loading the meta tags content from the backend. Despite seeing the proper content in the HTML, Facebook's debugger does not seem to recognize the tags. Has anyone else encountered ...

My custom filter consistently displays an array of objects with a length of zero

Currently, I am iterating over an array of objects in my view as shown below: <ion-list> <ion-item *ngFor= "let category of (productCategories | onlyhomecategory) " > <ion-icon name="arrow-forward" item-right></ion-icon&g ...

Steps for inserting a dropdown menu into a kendo grid

Hey there, I'm currently working on adding a drop-down list to a kendo-grid column but I'm facing an issue where the data is not loading into the drop-down list. My goal is to populate the data from an array. Here's the code snippet from t ...

using Typescript in an Angular2 application

Can anyone explain why I am receiving an error when attempting to declare a const? The error message states: Expecting new line or semicolon export class MyClass{ const ALLOC_INVESTORS = "Allocation Investors"; } ...

"Incorporating Angular and Node.js in an architectural design, emphasizing the use of

Starting with my idea, I want to create an application where users input data that is then stored in a database (which is functioning correctly so far). Eventually, I want users to be able to export this data. In the node.js backend, there are XML files a ...

Identifying and handling errors in the outer observable of an RXJS sequence to manage

Encountered a puzzling rxjs issue that has me stumped. Here's the scenario: I have two requests to handle: const obs1$ = this.http.get('route-1') const obs2$ = this.http.get('route-2') If obs1$ throws an error, I want to catch it ...

Setting the default value for Angular Material's select component (mat-select)

Many inquiries are focused on setting a default value to display in a "Select" control. In this particular case regarding Angular 8 template driven forms, the issue lies in the inability to show the default value in the mat-select when the button is clicke ...

How to customize the radio button style in Angular 11 by changing the text color

Hey guys, I'm working with these radio buttons and have a few questions: <form [formGroup]="myForm" class="location_filter"> <label style="font-weight: 500; color: #C0C0C0">Select a button: </label& ...

What are the steps to integrating standard Bootstrap into an Angular application?

There are times when the navbar class, collapse class, and dropdown toggle button may not be supported in an angular application even after installing Bootstrap with scripts. I am interested in finding out how I can ensure that every Bootstrap class is fu ...

Combine two Observable arrays into a single array and showcase their contents using ngFor within an Ionic 3 application

In my Ionic 3 project, I am fetching two arrays through API calls. My goal is to display the data from both arrays in the same line like this: [item1.1] [item2.1] [item1.2] [item2.2] [item1.3] [item2.3] Instead of displaying them like this: [item1.1] ...

Unable to bring in a TypeScript library that was downloaded from a GitHub fork repository

Currently, I am working on developing a GitHub app using the probot library. However, I have encountered an obstacle as outlined in this particular issue. It seems that probot does not offer support for ESM modules, which are crucial for my app to function ...

Add a new class to the Custom Repository

In my project, I have developed a class called S3Service that handles the task of uploading and deleting objects (such as images) from S3. Since I intend to utilize this "service" in various modules, I decided to create a custom module named UtilsModule wh ...

Tips for implementing CSS on a component's elements using its selector in Angular 7/8

I have been working on a unique Angular 7/8 application lately. One of the custom components I created is an input element with the selector <app-input></app-input>. This particular input comes with its own set of stylings, such as a default bo ...

Angular authentication guard does not redirect properly after returning a Promise<UrlTree>

My authentication guard is set up to control access to the /sign-in and /verify-email routes, allowing only users who are not logged in or have not verified their email: export const signInGuard: CanActivateFn = (activatedRouteSnapshot: ActivatedRouteSnap ...

The value of additionalUserInfo.isNewUser in Firebase is consistently false

In my application using Ionic 4 with Firebase/AngularFire2, I authenticate users with the signinwithemeailandpassword() method. I need to verify if it's the first time a user is logging in after registering. Firebase provides the option to check this ...