Skip to content

When using nested router-outlet, the back button exits the App #477

Closed

Description

@m-abs

I'm trying to add child-routes to my Angular Native App, but when I click my android back-button the App just exits.

I've tried to write an example to show what the problem it here: https://github.com/m-abs/angular2-seed-advanced/tree/child-router
It's based on Nathan Walker's angular2-seed-advanced as that's what we use in our project.

What I've done:

What happens:

  • I tap on the Button nsRouterLinks and the components are loaded. Even the ActionBar works per ChildComponent, which were a bit of a surprise.
  • Click on the devices back-button, exits my App right away.

What I'd expect:

  • I tap on the Button nsRouterLinks and the components are loaded
  • I click back and the go back to the previous component in history

More data:
I've tried tracing it to try and make heads or tail on it:

JS: ns-router: NSLocationStrategy.path(): /
JS: Router Event: NavigationStart(id: 1, url: '/')
JS: Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
JS: Router Event: RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/home/child1', state: Route(url:'', path:'') { Route(url:'home', path:'home') { Route(url:'child1', path:'child1') }  } )
JS: ns-router: NSLocationStrategy.path(): /
JS: ns-router: NSLocationStrategy.replaceState pushing new state: null, title: , url: /home/child1, queryParams: null
JS: ns-router: PageRouterOutlet.activate() inital page - just load component
JS: Router Event: NavigationEnd(id: 1, url: '/', urlAfterRedirects: '/home/child1')
JS: NativeLifecycle: fragment0[0]<Page(1)>.onCreateAnimator(0, enter, undefined): null
JS: ns-router: nsRouterLink.tapped: /home/child2 usePageRoute: true clearHistory: undefined transition: true
JS: ns-router: NSLocationStrategy._setNavigationOptions({"clearHistory":false,"animated":true})
JS: Router Event: NavigationStart(id: 2, url: '/home/child2')
JS: Router Event: RoutesRecognized(id: 2, url: '/home/child2', urlAfterRedirects: '/home/child2', state: Route(url:'', path:'') { Route(url:'home', path:'home') { Route(url:'child2', path:'child2') }  } )
JS: ns-router: NSLocationStrategy.path(): /home/child1
JS: ns-router: NSLocationStrategy.pushState state: null, title: , url: /home/child2, queryParams: null
JS: Router Event: NavigationEnd(id: 2, url: '/home/child2', urlAfterRedirects: '/home/child2')
JS: NativeLifecycle: NativeScriptActivity.onBackPressed;
JS: TNS Application - Suspended
JS: NativeLifecycle: NativeScriptActivity.onStop();
JS: NativeLifecycle: fragment0[0]<Page(1)>.onDestroyView()
JS: NativeLifecycle: HIDDEN fragment0[0]<Page(1)>; destroyed: true
JS: NativeLifecycle: fragment0[0]<Page(1)>.onDestroy()
JS: TNS Application - EXIT
JS: NativeLifecycle: NativeScriptActivity.onDestroy();

As you can see NSLocationStrategy.pushState(/home/child2) is called for the child-route, but after onBackPressed the App just exits.

Activity

  1. changed the title [-]nested router-outlet, back button exits app.[/-] [+]When using nested router-outlet, the back button exits the App[/+] on Sep 28, 2016
  2. m-abs commented on Sep 29, 2016

    @m-abs
    ContributorAuthor

    Minor update:

    If I add an listener for backButtonPressed on android and call routerext.back() myself iit works as expected.
    The action bar for the child routes won't have an back-btn, but I can live with that.
    See here: https://github.com/m-abs/angular2-seed-advanced/blob/child-router-android-back-button/nativescript/app/pages/app/app.component.ts#L58-L69

    But should this kind of workaround really be needed?

  3. vakrilov commented on Sep 30, 2016

    @vakrilov
    Contributor

    You pretty much answered yourself. In Android the back button is bound to the page navigation, which i s controlled by the . So when you tap back - you should go to the previous page (skipping all intermediate router-outlet navigations).

    The solution you found is a valid one, although _getStates() directly seem like a hack. I've done a PR(#481) that exposes a canGoBack() method the should make you code cleaner.

  4. vakrilov commented on Oct 3, 2016

    @vakrilov
    Contributor

    Closing this issue for now - please reopen if needed.

  5. SBD580 commented on Jan 22, 2017

    @SBD580

    @vakrilov what about nested page-router-outlet? I had expected that the back button will be acting on the inner page-router-outlet but instead it acting on the outer one. Is this as expected?

  6. vakrilov commented on Jan 23, 2017

    @vakrilov
    Contributor

    Yes, the reason for that is consistency between IOS and Android. In IOS the <Back button will take you to the previous page, so we do the same in Android.
    You can change the behavior by handling activityBackPressed and doing routerExtensions.back().

  7. SBD580 commented on Jan 23, 2017

    @SBD580

    I see. I thought page-router-outlet define pages, so going back to previous page should act on the inner one and only then on the outer (when no more routes left)

  8. sittingbool commented on Jul 9, 2017

    @sittingbool

    The whole Navigation structure is a mess in my opinion. Its the wrong way around and i always struggle a lot if i want to combine navigation controls like i am used to with ios. In iOS and many Android Apps nowadays you have a tab view and navigate the content of each tab. otherwise tabs make no sense. On a website you would navigate inside the tab too by pressing back. in nativescript the tabview is constructed to be inside the "UINavigationController". A back button should not change anything on the tabview but navigate its content backwards. To have an page-router-outlet that cant be wrapped into someting is a brake of that structure. Usually i want a tabview outside, sometimes also a side-drawer. and definitively i dont want it an each page but globally.

  9. vipul1905 commented on Nov 14, 2017

    @vipul1905

    I tried to use this function routerExtensions.back() on activityBackPressedEvent but I get error "cannot get property back". I have imported the RouterExtensions file as well. Could anyone help me out with this? Thanks.

  10. vakrilov commented on Nov 20, 2017

    @vakrilov
    Contributor

    Hey @vipul1905: Can you please make sure you are using the NativeScriptRouterModule in your application and that you are injecting the the RouterExtensions inside your component using the angular DI.

  11. sittingbool commented on Nov 20, 2017

    @sittingbool

    I certainly did. I used the template project where this was set already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions