nativescript-angular icon indicating copy to clipboard operation
nativescript-angular copied to clipboard

Nested Routing and ClearHistory: Error when route between nested routes

Open codeback opened this issue 8 years ago • 35 comments

I have two routes which have child routes:

  • Route A

    • Nested Route A1
    • Nested Route A2
  • Route B

    • Nested Route B1
    • Nested Route B2

If I navigate from 'Nested Route A2' to 'Nested Route B1' with clearHistory=true, then I can not navigate anymore between 'Nested Route B1' and 'Nested Route B2'.

This repo reproduces the issue. Steps to reproduce it:

  1. Navigate to 'Angular routing' -> 'Nested routers'
  2. Click on 'SECOND' button,
  3. Click in the big button 'This is second. Load first',
  4. Now, you are in the 'Angular Routing 2' component, but you can't navigate between the nested routes.

Please see this animation: nested_routing_clearhistory

The repo is using:

  • "nativescript-angular": "next",
  • "tns-core-modules": "next",

The problem occurs in both platforms (iOS an Android).

P.D. I know that there are several issues regarding clearHistory but I think this case is not reported. Sorry if I am wrong.

codeback avatar Oct 23 '17 15:10 codeback

Also have this issue with the latest.

EDIT:

Running the navigate through a zone resolves the issue for us.

sean-perkins avatar Oct 23 '17 16:10 sean-perkins

Hi @sean-perkins,

Do you mean something like the following?

this._zone.run(() => this._routerext.navigate(['/home/view-1'], {clearHistory: true}));

It doesn't work in my case :(

@vakrilov, @tsonevn have you been able to reproduce this issue? Is it related with the new route-reuse strategy?

codeback avatar Oct 24 '17 14:10 codeback

Hi @codeback - I managed to reproduce the issue with your project. What's interesting is that there are no exceptions thrown and navigation to another page still works. Navigation onside the nested router is not working.

@sean-perkins - Can you please share more detail on you solution using the zone. It might lead to some insights on the problem and eventually help solve it :)

vakrilov avatar Oct 25 '17 08:10 vakrilov

In our scenario, the problem only presented itself after upgrading the Angular and NS Angular dependencies to the latest. We were on ~3.1.3 (NS Angular) beforehand. We have a lazy-loaded module that navigates the user to another lazy-loaded module, inside an event listener on a WebView.

With no changes (only dependency upgrades and updating to NativeScriptCommonModule), the app would redirect to the lazy-loaded module and no change detection or life cycle events would occur. But, after swiping out a side drawer and tapping an action, the page would then load all the life cycle hooks.

If we logged out of our application (which sends us back to the original lazy-loaded module) and log back in, change detection occurs, but then all navigation events are broken. Active router links are set, but the page-router-outlet doesn't actually update the component rendered.

To solve this, we wrapped our initial navigate inside a zone.run, which fixed the problem globally. We haven't dug into it any further, as there are no logs and that makes it unproductive to debug.

sean-perkins avatar Oct 25 '17 15:10 sean-perkins

Almost the same scenario, except running inside zone does not work for me. Had to remove clearHistory temporarily until this gets resolved.

nikoTM avatar Oct 26 '17 14:10 nikoTM

In my case, remove clearHistory produces other undesirable side effects. And running inside zone does not work either. :(

In my app the problem is that the ending route is a nested route. In other words, clearHistory=true doesn't work if the destination route is a nested route.

My very ugly workaround is to put another route in the middle: From Route A, navigate to Route C with clearHistory=true and then, from Route C, navigate to the destination nested Route with clearHistory=true.

Hope it helps while the issue gets resolved.

codeback avatar Oct 27 '17 11:10 codeback

Similiar issue I am having, for the past week trying to fix it but Alas ! I am using clearHistory = true when the person starts the app again after previously logged in, so to by-pass the login screen. When clearHistory = true, i go to a parent route, which has children routes, these children routes are then used to navigate to different views in the same parent route using

this.router.navigate(['appointments'], {relativeTo : this.route});

but when clearHistory = true, nothing happens just like OP mentioned above.

At first I thought that the routes break, but the console does not throw any error for routes break.

P.S: without clearHistory apps behaves the way it should

HassanMoinn avatar Feb 25 '18 20:02 HassanMoinn

Not sure if this helps to isolate the exact issue, but I've narrowed the cause of this problem to when the NSRouteReuseStrategy clears out its state cache - specifically when the cached items are destroyed.

If the destroyComponentRef call within DetachedStateCache.clear is skipped, then child routing continues to work.

simonpietsch avatar Mar 09 '18 07:03 simonpietsch

Removing the destroyComponentRef call works for us as well. That seems like something that would create a memory leak though right?

llwt avatar Mar 14 '18 15:03 llwt

+1 Really important to address this.

anuragd7 avatar Mar 20 '18 11:03 anuragd7

After further investigation, the problem is related to the specific order of how the components are created and disposed - specifically the RouterOutlet.

When navigating and clearing history, the old page is destroyed after the new page is created. This means the new RouterOutlet calls onChildOutletCreated after the old RouterOutlet calls onChildOutletDestroyed. If these outlets have the same name, then the call to onChildOutletCreated reuses the existing OutletContext, before finally the call to onChildOutletDestroyed clears the outlet property of the same OutletContext, leaving the new RouterOutlet in a non-working state.

I haven't confirmed this yet, but I imagine that this occurs in a different order when using straight RouterOutlets (that is, not a top-level PageRouterOutlet)

simonpietsch avatar Mar 21 '18 00:03 simonpietsch

+1

Randomgnome avatar May 03 '18 00:05 Randomgnome

Does anyone have a work around for this? It's causing me some headaches.

Randomgnome avatar May 03 '18 21:05 Randomgnome

We are some big router-related improvements for the 6.0.0 release. We will try resolve this as well, if possible.

vakrilov avatar May 04 '18 06:05 vakrilov

@Randomgnome I worked around this by creating an intermediary view, that has no nested views, that redirects to the desired view. But to fully work, the redirect from the intermediary view had to be in a timeout.

In short, save somewhere the routing info for the view you want to redirect to, then redirect to the intermediary view, then use the saved data to redirect from the intermediary view to where you actually wanted in a timeout (200ms, for example).

Laureckis avatar May 04 '18 07:05 Laureckis

@Randomgnome I initially attempted to work around this by overriding methods of the router classes to change how child router outlets were disposed (essentially, updating onChildOutletDestroyed to only clear the outlet property of its OutletContext if it matches the expected outlet). Although this worked after the initial navigation, after the second, routing stopped as before.

In the end, we worked around this by updating one page so that it no longer used nested routes to display content. Definitely not ideal, but we encountered some performance issues with routing that ultimately meant this may have actually been a better fit for what we were looking to achieve.

Looking forward to having this resolved - hopefully 6.0.0 can resolve some of these other issues too.

simonpietsch avatar May 09 '18 13:05 simonpietsch

Any news on this?

gabitoesmiapodo avatar Jun 19 '18 18:06 gabitoesmiapodo

Hi all, Can you reproduce this issue with the latest tns-core-modules4.1.0 and nativescript-angular 6.0.0?

tsonevn avatar Jul 19 '18 11:07 tsonevn

@tsonevn I have reproduced this with the most current version of tns-core-modules and nativescript-angular and the above repo.

vcooley avatar Jul 19 '18 15:07 vcooley

Any news on this? Still have this bug with latest versions.

LeoDupont avatar Oct 04 '18 15:10 LeoDupont

Umm Okay, it's still Open

royryando avatar Oct 17 '18 09:10 royryando

still open

Nick-lab avatar Nov 26 '18 15:11 Nick-lab

Can confirm this is still a problem with nativescript-angular 7.1 and tns-core-modules 5.1. Also wanna point out that this is in the backlog for 6.2, and that ship seems to have sailed.

larssn avatar Dec 13 '18 17:12 larssn

Setup is a little different, but here's a playground that shows the error: https://play.nativescript.org/?template=play-ng&id=df0v5O&v=5

pnahtanoj avatar Jan 15 '19 22:01 pnahtanoj

My application's navigation wasn't working as well. I spent 5 hours to just discover this bug. This should be fixed.

erkanarslan avatar Feb 08 '19 13:02 erkanarslan

Still an issue (Angular 7.2.6 & NativeScript 5.2.1).

If it's helpful, a possible workaround to this problem is to create a new Custom Route Reuse Strategy.

ivadym avatar Feb 28 '19 15:02 ivadym

Honestly, never could thought about this. It's the situation where google can't help. Only found info about this issue after discovering it by myself

AndrePu avatar Oct 17 '19 22:10 AndrePu

Still having this problem too 😔 any news about a fix?

yahyaKacem avatar Dec 02 '19 10:12 yahyaKacem

I have it on latest 6.2.2

yahyaKacem avatar Dec 02 '19 11:12 yahyaKacem

I have the same bug on 6.3.0 ... I spent half a day just for identify it's a bug and when it happens ... now to see that it's a 2 year old bug is really annoying. Any news on it?

msteini82 avatar Jan 05 '20 05:01 msteini82