Using Nested Router Outlets with NativeScript and Angular

Intro

Sometimes we need only a part the page in our app to change from one component to another, while we want the rest of the page to stay where it is.

Imagine you have a tab-view with multiple tabs and you want each tab to navigate independently of the whole page. You could try to hack that by adding all required components in each tab, then show and hide them with a clever *ngIf. However the moment you add a couple of these you realise that this wasn't such a clever approach after all.

This is when Angular comes to the rescue with the magic of named router outlets. The idea is that you can add multiple router-outlets with to your page, give each a unique name and then navigate to each by simply providing the name of the router-outlet and the destination path.

Before we dive into the code. I assume that you have the core knowledge of how to create Angular components, services and how to add these to @NgModule.

The plan

We are going to build an app with one page (HomeComponent), which will contain a tab-view with two tabs. One tab will display a list of dogs (DogsComponent) and when you click on one, you will be redirected to the dogs details view (DogDetailsComponent). The second tab will be very similar except this time we will display a list of cats (CatsComponent) and cat details (CatDetailsComponent).

Let's get our hands dirty

We are going to implement our solution in the following steps:
- Choose the right router outlet at the root,
- Configure routing for cats and dogs,
- Build navigation for cats using nsRouterLink,
- Build navigation for dogs with code.

Select the root router outlet

Named router outlets work only with router-outlet at the root, as page-router-outlet navigates to a whole different page each time we call navigate.
Therefore we need to go to app.component.html and change it to:

<router-outlet></router-outlet>

Configure routing

Since we know what components we will need we are going to start with configuring our routes (see app.routing.ts).

We will need to configure the routes for cat and dog related components are configured as children of the home route.

Also each of these children routes will need an outlet property, which will indicate which router-outlet this route belongs to. So each cat component should be assigned to 'catoutlet', while each dog component should be assigned to the 'dogoutlet'.

[Note] the outlets names don't need to include the word outlet, however the name should contain only alpha-numeric characters. For example 'cat-outlet' will not work.

Additionally we can select which components to show by default when the app loads for the first time. This can be done by changing the redirectTo property on the default route. In our case we want to show CatsComponent and DogsComponent first, so our redirectTo should be '/home/(catoutlet:cats//dogoutlet:dogs)'

[Note] If you needed to navigate to CatDetails by default, you could set redirectTo to '/home/(catoutlet:cats/Betsy//dogoutlet:dogs)' or '/home/(catoutlet:cats/Betsy)'

Configure router-outlet's

Now let's implement the home component.
This component will serve us as a simple container for two both router-outlets. So the HomeComponent class is rather empty.
The whole magic will happen in the HomeComponent template, which should contain a tab view with two instances of a named router-outlet.
Naming a router-outlet is as simple as setting the name property. Following the routes configuration, we need to name the router-outlets "catoutlet" and "dogoutlet".

[nsRouterLink] navigation for Cats

Now let's implement CatsComponent and CatDetailsComponent.

The CatsComponent template is quite simple. It should have a bunch of buttons each navigating to CatDetailsComponent with a name of a cat as a parameter.
To do that we need to use nsRouterLink with the following parameters:
- path to the parent router-outlet (in this case it is '/home')
- outlets configuration, with the name of the outlet we want to update (in this case it is catoutlet) plus the route for the outlet (in this case ['cats', 'cats-name'])
Like this:

And voila! That is all we need to do, to navigate inside catoutlet with nsRouterLink.

Code navigation for Dogs

For the dogs part of the app we will navigate with code, by using the navigate function of the Router service from @angular/router (you know the drill - just import it and then inject it in the constructor).

In the DogsComponent class we need a function that takes dog's id and then navigate to DogDetailsComponent.navigate() takes exactly the same parameters as nsRouterLink, just this time we will use dogoutlet.

Navigating multiple outlets

You can also navigate to more than one outlet in a single call.
Just simply provide all outlets you want to update in the outlet param.
For examle we can add a reset button that will navigate to the default of cats and dogs views just do it like this: