fabernovel loader

Sep 28, 2017 | 4 min read

Tech

Angular Modules

Emilie Paillous

Developer


FABERNOVEL TECHNOLOGIES
While a project is being developed, the more the features are numerous, the more difficult it is to comprehend the code. Angular offers a division through modules, that allows splitting the different features of the application. There is a strong correlation, or even a total equivalence between the different modules of an Angular application and the business features of the project.

The App Module

The main and first module of the application is the AppModule. Before dividing the application into different modules, the App module holds the entire application. After the division, its role is to import the modules provided by Angular (BrowserModule, BrowserAnimationsModule etc.), and then each of the submodules.

There are three types of « sub-modules »:

  • CoreModule: it is unique within the application. It must only be imported into the AppModule. It mainly contains singleton services that are common to the whole application (for instance, an AuthService that allows access to the current user from anywhere in the application), as well as components used only in the AppComponent template (for example, the application menu, the navigation bar, etc.)
  • SharedModule: Also unique within the application, it contains all components that are common to the application. It must not provide any services (see here).
  • FeatureModule: As its name implies, it is a module specific to a “feature”. In our case, each menu entry is a feature module. We also have an « admin » FeatureModule that provides access to application administration (only for authorized users). This division into FeatureModule also makes it possible to separate the code cleanly in order to have two developers easily work in parallel on different features without having to modify the file app-module.ts. A FeatureModule can provide services specific to its module, their lifetime will be the same as that of the module. For instance, if your application offers a notifications system, it is appropriate to have a NotificationsModule that contains the component displaying the notification list, the corresponding service, the notification detail component, and so on.

 

This summary table makes it possible to quickly know which type of module matches a given situation.

Let’s assume that you have an « articles » module allowing you to list articles, and an « admin » module managing the private area of the application. This is the AppModule after applying this breakdown:

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

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

import { BrowserAnimationsModule } from

'@angular/platform-browser/animations';


/* Routing Module */

import { AppRoutingModule } from './app-routing.module';


/* App Root */

import { AppComponent } from './app.component';


/* Feature Modules */

import { CoreModule } from './core/core.module';

import { ArticlesModule } from './articles/articles.module';

import { AdminModule } from './admin/admin.module';


/* Widget Modules */

import { SharedModule } from './shared/shared.module';


@NgModule({

    imports: [

 BrowserModule,

 BrowserAnimationsModule,

 SharedModule,

 AppRoutingModule,

 CoreModule,

 ArticlesModule,

 AdminModule     ],

    declarations: [ AppComponent ],

    bootstrap: [ AppComponent ]

})

export class AppModule { }

 

The routing modules

 

There is in fact a fourth type of module, which the tutorial proposes to classify in the category of features modules but which we prefer to distinguish for the sake of clarity: the routing modules. These modules only aim to define a set of routes and sub-routes allowing the link between a URL address and the component to be displayed. Moreover, the routing modules provide « guards » regulating access to a route. Here is an example:

 

const routes: Routes = [

{ path: 'login', component: LoginComponent },

{ path: '**', redirectTo: '/login', pathMatch: 'full' }

];

@NgModule({

imports: [RouterModule.forRoot(routes)],

exports: [RouterModule],

providers: [AuthGuard]

})

export class AppRoutingModule { }

 

This refers to the main routing module of the application, the AppRoutingModule. In this module, a main route is established, the /login route accessible to all users. This module also provides the « AuthGuard », which verifies that a user is authenticated.

Let’s analyze now the ArticlesRouting module, imported by the ArticlesModule module, the latter having been imported by the AppModule.

 

const routes: Routes = [

  { path: 'articles', canActivate: [ AuthGuard ],

  children: [

    { path: '', component: ArticlesListComponent }

    { path: ':id', component: ArticleDetailComponent }

  ]

 }

];
@NgModule({

imports: [RouterModule.forChild(routes)],

exports: [RouterModule]

})

export class ArticlesRoutingModule { }

 

Here, we are defining:

  • the /articles route that displays the list of items
  • the /articles/:id route that allows you to display the detail of an article

These two routes are only accessible if the user is authenticated, that is if he passes the « AuthGuard » provided by the AppRoutingModule.

Finally, this is the AdminRouting module that allows defining the routes of the admin panel:

 

const routes: Routes = [

{ path: 'admin', canActivate: [ AuthGuard, AdminGuard ],

children: [

{ path: 'users', component: UsersListComponent }

]

}

];


@NgModule({

imports: [RouterModule.forChild(routes)],

exports: [RouterModule],

providers: [AdminGuard]

})


export class AdminRoutingModule { }

 

This module defines a single /admin/users route allowing an authenticated user and administrator to access the list of users.

The AdminGuard is provided in the AdminRoutingModule since it is only used in the context of this module.

Make sure you are using imports: [RouterModule.forChild(routes)] and not imports: [RouterModule.forRoot(routes)] in all the application’s feature modules. A call to forRoot in a child component, as well as lazy-loaded, can cause an error at execution.

 

Lazy Loading

In some cases, it is not necessary to load the entire application at startup. For example, a non-admin user will never have access to the admin panel of the application. Therefore, he will never need to use the Admin module. To avoid this useless import, you can use the lazy load so that it is loaded only when it is actually needed.

For each module you wish to lazy load, you just have to define the route associated with the module in the routing app. Let’s assume that we want to load the Admin module while keeping the Article module eagerloaded. Here’s what the AppRoutingModule becomes:

 

const routes: Routes = [

{ path: 'login', component: LoginComponent },

{ path: 'admin', loadChildren: './admin/admin.module#AdminModule', canActivate: [AuthGuard, AdminGuard] },

{ path: '**', redirectTo: '/login', pathMatch: 'full' }

];


@NgModule({

imports: [RouterModule.forRoot(routes)],

exports: [RouterModule],

providers: [AuthGuard, AdminGuard]

})


export class AppRoutingModule { }

 

AdminRoutingModule devient :

 

const routes: Routes = [

{ path: 'users', component: UsersListComponent}

];


@NgModule({

imports: [RouterModule.forChild(routes)],

exports: [RouterModule]

})


export class AdminRoutingModule { }

 

Now the AppRoutingModule is providing the AdminGuard to prevent the module from being loaded while the AuthGuard and AdminGuard have prevented access to that route. In addition, the AdminModule is no longer imported into the AppModule. It is therefore only loaded when accessing the /admin/users route as a logged in user and administrator.

Make sure you do not overuse the lazy load. If the loading time of the first page of a typical user is reduced, an administrator will have to wait a little longer (the time that the module loads) to access the Admin panel. A balance must be struck between the use of the module and the loading time at start-up.

 

Willing to discuss about Angular Modules with us ?

Contact Emilie
This article belongs to a story
logo business unit

FABERNOVEL TECHNOLOGIES

150 talents to face technological challenges of digital transformation

next read