Nativescript-angular: Root with <page-router-outlet> disables <router-outlet>

Created on 29 Dec 2016  路  17Comments  路  Source: NativeScript/nativescript-angular

_From @onury on December 29, 2016 1:56_

Please, provide the details below:

Did you verify this is a real problem by searching [Stack Overflow]

Yes. Couldn't find a solution, created a new thread here. Answered here.

Tell us about the problem

If the app is bootstrapped with a component that has a <page-router-outlet>; it ignores any <router-outlet> within a (sub) page/component and nsRouteLink will navigate to a new page instead of loading the target component in the router-outlet.

Which platform(s) does your issue occur on?

iOS
Android not tested.

Please provide the following version numbers that your issue occurs with:

  • CLI: 2.4.2
  • Cross-platform modules: 2.4.4
  • Runtime(s): tns-ios: 2.4.0
  • Plugin(s): 2.4.3

Please tell us how to recreate the issue in as much detail as possible.

  • Create/configure the simplest app via tns with --ng support.
  • Modify the bootstrapped app.component.ts and include a <page-router-outlet>.
  • Use the official example to create other components such as FirstComponent, SecondComponent.. and configure.
  • Add a HomeComponent to include a <router-outlet> and link buttons to /first and /second (like in the example).
  • Run.

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.

app.component

@Component({
    selector: "main",
    template: "<page-router-outlet></page-router-outlet>"
})
export class AppComponent {}

home.html (of HomeComponent)

    <StackLayout>
        <StackLayout>
            <Button text="First" [nsRouterLink]="['/first']"></Button>
            <Button text="Second" [nsRouterLink]="['/second']"></Button>
        </StackLayout>
        <router-outlet></router-outlet>
    </StackLayout>

first.html (of FirstComponent)

        <StackLayout>
            <Button text="This is FIRST. Load SECOND" [nsRouterLink]="['/second']"></Button>
        </StackLayout>

second.html (of SecondComponent)

        <StackLayout>
            <Button text="This is SECOND. Load FIRST" [nsRouterLink]="['/first']"></Button>
        </StackLayout>

app.routing

export const routes:Routes = [
    { path: "", redirectTo: "home", pathMatch: "full" },
    { path: "home", component: HomeComponent },
    { path: "first", component: FirstComponent },
    { path: "second", component: SecondComponent }
];

_Copied from original issue: NativeScript/NativeScript#3378_

question

Most helpful comment

Has anything changed here?

Following this example exactly simply doesn't work:
https://docs.nativescript.org/ui/modal-view-ng#modal-view-navigation

As @onury mentions in his use case, the following error is thrown at first
Error: No provider for ModalDialogParams!

After adding it to app.module.tns.ts
JS ERROR Error: Can't resolve all parameters for ModalDialogParams: (?, ?).

Seems odd that this example in the documentation doesn't work.

All 17 comments

Any news on this? I'm sure this is affecting many devs.

Hey @onury I have tested the described scenario on my side and everything seems to work as expected (both page-router-outlet and router-outlet are working).
For your convenience I have created a test project here - you can clone it and test it on your side.

Hi @NickIliev. I downloaded and tested your test app (made no changes), it doesn't work as expected. <router-outlet> is still bypassed. Links navigate to new pages.

See the image below:
https://s28.postimg.org/3jy8m4x8t/Simulator_Screen_Shot_30_Dec_2016_16_00_29.png

What version of Xcode do you have?
I have Xcode v8.2.1. Testing on iOS 10.2 emulator.

@onury You are right - the nested router-outlet is bypassed with this logic - I will investigate and come back to you when I have more info.

Hey @onury I've researched this case and in order for the router-outlet to work as nested one (for page-router-outlet or for another router-owlet as well) it must pass its links via children argument.
e.g.

const routes: Routes = [
    {
        path: '',
        component: ItemsComponent,
        children: [
            { path: "first", component: FirstComponent },
            { path: "second", component: SecondComponent }
        ]
    }
];

I've revised the sample app (now with the working updated logic)

@NickIliev I've already tried that. But still downloaded your update and just tested. Still doesn't work. If it's working for you, I suspect it's Xcode/iOS version.

Also pls see my SO thread here for things I tried.

  • children routing doesn't help.
  • named router-outlet doesn't help.

I've just tried the sample app on Android, it works as I'd expect it to.
I don't have an mac at the moment, so I couldn't test it on iOS.

Sorry it was still building the old sample app somehow.
Cleared everything, re-built.
I confirm it works on iOS with children paths.

Thanks for your help @NickIliev.
(This should clearly be indicated in the docs, though)

Demo example for nested router outlets added in nativescript-sdk-example-ng

Thanks @NickIliev.
Would it be possible to add an example for nested router-outlet within a modal?

  • It throws Error: No provider for ModalDialogParams!
  • If I add a provider for it, it will then throw Can't resolve all parameters for ModalDialogParams: (?, ?) and exit.
  • If I remove nested router from modal, it works.
  • If I test on normal page instead of modal, it works.

...any tip would be very much helpful.. Nothing on StackOverflow..
I suspect this might be a bug..

@onury indeed using NativeScriptRouterModule with module page won't work. You can try to use the native @angular router, but this will cause additional complication as you will need to clean your routes manually.

Overall I would not recommend using a complicated navigation inside a module page as the module page is meant to be more like an extended dialogue rather than a sub-app module with various waterways.
What you can do to overcome this is to implement hidden elements in your module page and show them when needed while hiding the others (for example using a segmented bar).
Or you can use angular structural directives like here to create your internal architecture.

All code posted here is OUT OF DATE, it leads to 404 pages. is a dead end

Has anything changed here?

Following this example exactly simply doesn't work:
https://docs.nativescript.org/ui/modal-view-ng#modal-view-navigation

As @onury mentions in his use case, the following error is thrown at first
Error: No provider for ModalDialogParams!

After adding it to app.module.tns.ts
JS ERROR Error: Can't resolve all parameters for ModalDialogParams: (?, ?).

Seems odd that this example in the documentation doesn't work.

To make things even more bonkers, there's a clear example here: https://github.com/NativeScript/nativescript-sdk-examples-ng/tree/master/app/ng-ui-category/modal-view-ng/modal-view-navigation

So clearly this must be possible... or perhaps I'm missing a recent change.

@onury indeed using NativeScriptRouterModule with module modal page won't work. You can try to use the native @angular router, but this will cause additional complication as you will need to clean your routes manually.

Overall I would not recommend using a complicated navigation inside a module modal page as the module modal page is meant to be more like an extended dialogue rather than a sub-app module with various waterways.
What you can do to overcome this is to implement hidden elements in your module modal page and show them when needed while hiding the others (for example using a segmented bar).
Or you can use angular structural directives like here to create your internal architecture.

Unfortunately I couldn't disagree more with the statement that there shouldn't be page navigation within a modal. This is pretty standard behavior for various interfaces within iOS, and is critical to establish sub-process user-flows.

So we have an app with the following structure:

   -> router-outlet
           -> router-outlet(primary)
           -> router-outlet(details)

modalService.showModal() only works in the two outer outlets, and we get the Error: No provider for ModalDialogParams! when the deeper routes try to use showModal().

Was this page helpful?
0 / 5 - 0 ratings

Related issues

igorls picture igorls  路  3Comments

samuelvisscher picture samuelvisscher  路  3Comments

pkoleva picture pkoleva  路  3Comments

sarvagayatri picture sarvagayatri  路  3Comments

EricRobertBrewer picture EricRobertBrewer  路  3Comments