Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement multi-level routing in Angular?

I'm working on a little project of mine in order to learn something more about Angular, but I really cannot figure out how to implement a multi-leveled routing.

I've read the documentation about the new release of the Router Component and also some other topics on StackOverlfow (first, second, third), but I cannot find a solution to my problem.

Let's consider the following app structure, without considering the Test and Test2 blocks.

App structure

And let's consider the components of my app as following:

main.ts

import { bootstrap }    from '@angular/platform-browser-dynamic';

import { MyAppComponent } from './my-app/my-app.component';
import { APP_ROUTER_PROVIDERS } from './my-app/my-app.routes';

bootstrap(MyAppComponent, [ APP_ROUTER_PROVIDERS ])
    .catch(err => console.error(err));

my-app.component.ts

import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';

@Component({
    selector: 'my-app',
    template: '<router-outlet></router-outlet>',
    directives: [ROUTER_DIRECTIVES],
})

export class MyAppComponent { }

my-app.routes.ts

import { provideRouter, RouterConfig } from '@angular/router';

import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { SignUpComponent } from './sign-up/sign-up.component';

import { AdminRoutes} from './admin/admin.routes';

export const routes: RouterConfig = [
  { path: '', component: HomeComponent },
  { path: 'login', component: LoginComponent },
  { path: 'sign-up', component: SignUpComponent },
  ...AdminRoutes,
];

export const APP_ROUTER_PROVIDERS = [
    provideRouter(routes)
];

admin.component.ts

import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';

@Component({
    selector: 'admin',
    template: 'Hello I am ADMIN <br> <router-outlet></router-outlet>',
    directives: [ROUTER_DIRECTIVES]
})

export class AdminComponent { }

admin.routes.ts

import { RouterConfig } from '@angular/router';

import { AdminComponent } from './admin.component';
import { MainPageComponent } from './main-page/main-page.component';
import { SettingsComponent } from './settings/settings.component';

export const AdminRoutes: RouterConfig = [
  {
      path: 'admin',
      component: AdminComponent,
      children: [
        { path: 'main-page', component: MainPageComponent },
        { path: 'settings', component: SettingsComponent },
      ]
  }
];

main-page.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'main-page',
    template: 'Hello I am MAIN PAGE!!!'
})

export class MainPageComponent { }

settings.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'settings',
    template: 'Hello I am SETTINGS!!!'
})

export class SettingsComponent { }

When I try to use such a configuration nothing works anymore and the browser's console is full of errors.

This happens only when I add the children[...] in the admin.routes.ts, and I think the problems come in there.

  1. Could you give me any hint on how I can implemented properly, please?
  2. Am I missing anything?
  3. Is there a better way?

Thank you in advance for your help and I hope what I've written in the post it's helpful to understand my issue!

like image 747
starscream Avatar asked Jul 03 '16 09:07

starscream


People also ask

Can we have multiple router outlet in Angular?

Angular Router supports multiple outlets in the same application. A component has one associated primary route and can have auxiliary routes. Auxiliary routes enable developers to navigate multiple routes at the same time.

How does Angular implement routing?

First, add links to the two components. Assign the anchor tag that you want to add the route to the routerLink attribute. Set the value of the attribute to the component to show when a user clicks on each link. Next, update your component template to include <router-outlet> .

Can Angular 12 use multiple router outlets?

Using named outlets and secondary routes, you can target multiple outlets in the same RouterLink directive.


1 Answers

Angular router considers a route with children as a non-terminal route and routing happens to terminal routes only. Angular router expects route to have a default entry for path: ''.

To resolve this issue you should add a redirect from the parent route to one of the child routes.

export const AdminRoutes: RouterConfig = [
{
    path: 'admin',
    component: AdminComponent,
    children: [
        { path: '', redirectTo: 'main-page', terminal: 'true' },
        { path: 'main-page', component: MainPageComponent,
        { path: 'settings', component: SettingsComponent },
    ]
 }];

Edit: if using rc4 and router 3.0.0-beta2 they have renamed terminal to pathMatch. So update the redirect route as below:

{ path: '', redirectTo: 'main-page', pathMatch: 'full'},
like image 58
Arpit Agarwal Avatar answered Oct 16 '22 09:10

Arpit Agarwal