Routing Between Modules In Angular

Routing Between Modules In Angular

In this article, we will learn how to set up routing between numerous feature modules. We learned how to develop several feature modules in an application in the last Angular Modules article. Modules are the foundation of all Angular apps. Our app will include numerous of these modules, each of which will implement a different feature.

Routing

Let's have a look at how routing is set up in the application's root module.

Defining the routes

In the example below, the routes are defined as a constant.

const appRoutes={ path: 'home',   component: HomeComponent }

The path is the URL section, and the component to be loaded is the component. When the user navigates to the URL "/home," this route instructs angular to render the HomeComponent.

Register the Routes

Then, as shown below, we register the routes with the RouterModule in our AppModule.

imports: [RouterModule.forRoot(routes)],

Display the Component

The RouterLink directive will then be used to tie the click event to Route.

<li><a home="" routerlink="">Home</a></li>

The component is then displayed using the router-outlet directive, as illustrated below.

<router-outlet></router-outlet>

Routing in Feature Module

Except for how we register the routes with the RouterModule, routing in Feature Modules or Sub Modules follows the same paradigm.

The forRoot (RouterModule.forRoot(routes)) function will be used in the Root module, whereas the forChild (RouterModule.forChild(routes)) method will be used in feature modules.

forRoot vs forChild

The RouterModule is made up of various parts. It also encompasses a number of services.

The Root Module's services, as well as those supplied by any of the eagerly loaded feature modules, are app-scoped. i.e., they can be injected into any component of the software.

The lazy-loaded modules are exempt from this rule. The injector and providers for the lazy-loaded modules are separate. The services supplied by lazy loaded modules are only available in lazy loaded modules.

Consider the example of importing RouterModule into a lazy loaded module. In the lazily loaded module, this will generate a separate instance of the Router service. Because there should only be one instance of the Router service in the app, there will be unattended problems.

The services must be registered only in the AppModule, not in the Lazy loaded module. RouterModule is imported and all of its services are registered in the forRoot function. As a result, it's included in the root module. RouterModule is imported via the forChild method, but its services are not registered. As a result, all other modules should be included.

Example App

Using the Angular CLI command, create an Angular app.

ng new --routing  --style css ModuleDemo

Creating the Feature Module

Let's make an AdminModule feature module. To begin, make an admin folder in the app folder.

Add the following code under the user.component.ts file:

import { Component } from '@angular/core';
 
@Component({
  template: '<h1>User Component</h1>',
})
export class UserComponent {
  title = '';
}

Now, Open the rights.component.ts file and put the following code:

import { Component } from '@angular/core';
 
@Component({
  template: '<h1>Rights Component</h1>',
})
export class RightsComponent {
  title = '';
}

Add the following code under the dashboard.component.ts file:

import { Component } from '@angular/core';
 
@Component({
  template: '<h1>Dashboard Component</h1>',
})
export class DashboardComponent {
  title = '';
}

Routing Module

The routing module for the aforesaid components is the next stage.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
 
import { UserComponent } from './user.component';
import { RightsComponent } from './rights.component';
import { DashboardComponent } from './dashboard.component';
 
const routes: Routes = [
    {   path: 'user',   component: UserComponent   },
    {   path: 'rights',   component: RightsComponent   },
    {   path: 'dashboard',   component: DashboardComponent   },
  ];
 
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class AdminRoutingModule { }

The routes are described as follows:

const routes: Routes = [
    {   path: 'user',   component: UserComponent   },
    {   path: 'rights',   component: RightsComponent   },
    {   path: 'dashboard',   component: DashboardComponent   },
  ];

and RouterModule.forChild(routes) is imported, which registers the routes with the router but does not construct the router service.

Root Module

Add the following code under the admin.module.ts file:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
 
import { AdminRoutingModule } from './admin.routing.module';
 
import { UserComponent } from './user.component';
import { RightsComponent } from './rights.component';
import { DashboardComponent } from './dashboard.component';
 
@NgModule({
  declarations: [UserComponent,RightsComponent,DashboardComponent],
  imports: [
    CommonModule,
    AdminRoutingModule,
  ],
  providers: [],
})
export class AdminModule { }

Add the following code under the app.module.ts file:


Finally, the AdminModule must be imported into the AppModule.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
import { AdminModule} from './admin/admin.module';
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    AdminModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Add the following code under the app-routing.module.ts file:

The AppRoutingModule contains the AppModule's routing information, which is currently empty in the example. Routs are registered using the forRoot method, which registers both the routes and the routing-related services.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
 
const routes: Routes = [];
 
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

The AppRoutingModule is then imported into the AppModule.

To app.component.css, add the following CSS styles.

ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #333333;
}
 
li {  float: left; }
 
li a {
    display: block;
    color: white;
    text-align: center;
    padding: 16px;
    text-decoration: none;
}
 
li a:hover { background-color: #111111; }

Child Routes

The URLs in the preceding example are /user, /dashboard, and /rights. Using the following routes, you may modify the URL to admin/dashboard, admin/user, and admin/rights.

const routes: Routes = [
    {   path: 'admin',   component: DashboardComponent,
        children :[
            { path: 'dashboard', component: DashboardComponent},
            { path: 'user', component: UserComponent},
            { path: 'rights', component: RightsComponent},
        ]
    },
];

Both /admin and /admin/dashboard lead to the DashboardComponent in the example above.

In the app, you must make the necessary adjustments in app.component.html.

<ul>
  <li>
    <a routerlink="/admin/dashboard">Dashboard</a>
  </li>
  <li>
      <a routerlink="/admin/user">User</a>
  </li>
  <li>
    <a routerlink="/admin/rights">Rights</a>
  </li>
</ul>
 
<router-outlet></router-outlet>

Menu in  Feature Module

Change your routes to

const routes: Routes = [
    {  path: 'admin', component: DashboardComponent,
       children :[
           { path: 'user', component: UserComponent},
           { path: 'rights', component: RightsComponent},
       ]
    },
];

In DashboardComponent, add the Menu.

import { Component } from '@angular/core';
 
@Component({
  template: `<h1>Dashboard Component</h1>
   
  <ul>
    <li><a routerlink="user">User</a></li>
    <li> <a routerlink="rights">Rights</a></li>
  </ul>
  <router-outlet></router-outlet>
  `,
})
export class DashboardComponent {
  title = '';
}

Remove it from app.component.html as well.

<ul>
  <li>
    <a routerlink="/admin">Admin</a>
  </li>
</ul>

<router-outlet></router-outlet>

Wild card route

Every URL fits the (**) wild card route, so it must be placed last. When the URL does not match any routes, this is used to display the Page Not Found error message.

{ path: '**', component: NotFoundComponent }

Add a new component not-found.component.ts to the AppModule.

import { Component } from '@angular/core';
 
@Component({
  template: '<h1>Not Found</h1>',
})
export class NotFoundComponent {
  title = '';
}

Include the NotFoundComponent in the AppRoutingModule.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
 
import { NotFoundComponent } from './not-found.component';
 
const routes: Routes = [
  { path: '**', component: NotFoundComponent }
];
 
@NgModule({
  declarations:[NotFoundComponent],
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Move the AppRoutingModule to the end of the imports in AppModule. As a result, the wild card route will always be at the bottom of the list.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
import { AdminModule} from './admin/admin.module';
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AdminModule,
 
    AppRoutingModule,   //this must be called last
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Conclusion

We learned how to define routes in feature modules in this module. We also looked at how to implement wildcard and child routes.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in the comment section.

Post a Comment

Previous Post Next Post