Search code examples
angularionic-frameworkangular-routerangular-lifecycle-hooksionic-tabs

Ionic Angular router component caching issue


Currently, I am developing an Ionic 5 application with Angular 9 (Single page app) and I am having some issues regarding the routing/component caching (At least that is what I think) and would need a bit of help. I will try to explain my situation the best that I can so that you can grasp the concept and the issue I am battling with.

I have one page on which I have 2 <ion-tab-bar> controls / tabs (Active and Inactive). On the Active tab, I am listing the products from my database which have the 'active' flag set on them in the DB, and on Inactive I am listing the opposite ones. On these tabs, the products are shown in a list-oriented way, styled as cards/card components.

After I click on a card I navigate the user to a new page (/active/:id) on which I show the product details. Among other features, there is a button that marks the product as Inactive. By clicking this button I am making an api call which marks the product as Inactive in the db. Also, this page contains a <ion-back-button> button component which brings me back to the previous page that I was on.

The problem

My issue is, that when I mark the product as Inactive, it changes its state in the db, but when I click on the back button and return to the Active tab, the product which I marked as Inactive is still under the Active tab, and I noticed that none of the lifecycle methods are being called, nor is the api call being executed in order to refresh the list.

After this, when I go to the Inactive tab, now my product is shown here, and when I switch to the Active tab again, it's no longer under Active tab, what I would expect in the first place.

This behavior does not only happen when I navigate through the back button, but it also happens when I navigate through the header navigation (Because of this, I think this is not related to rendering the page from location history).

I'm posting an image below, which visually represents the problem.

Any suggestions/guidelines would be appreciated. Thanks in advance.

enter image description here


Solution

  • Background:

    Ionic uses a route strategy that preserves the UI state while navigating. For that reason, Ionic provides the life cycle methods to properly watch for the view changes. Unfortunately, these life cycle methods only work when navigating between routes of the same <ion-router-outlet>.

    In the Ionic app, <ion-tabs> internally uses an <ion-router-outlet?. So the life cycle methods declared inside the individual tab component are only called when navigating between the tabs.

    In your app, when you are navigating to /active/:id, you are essentially moving out of the component which contains <ion-tabs> and going to the component mentioned in the /active/:id route. This change of view happens in the <ion-router-outlet> you have specifically used in your project.

    So Coming to the solutions, there are two approaches you can try.

    1. Use Ionic Lifecycle methods in the component where <ion-tabs> is used

    In the component where you have used <ion-tabs>, add ionViewWillEnter method. Since you are using ngRx, you can call an action to refresh the products list in the application state. This way, when you are on a specific tab - Active / Inactive, you will have the refreshed products data readily available on the UI.

    2. Subscribe on the router URL

    In this approach, you will have to subscribe to the router URL in your Active and Inactive tabs. Whenever the UI navigates to that specific route, we can watch on the changes and refresh the products list.

    Since I was not using ngRx in my project, I had to use the second approach to refresh the data on my app. The complete code for the second approach is mentioned here.

    Let us know which approach worked for you.