How To Work With Multiple Modules In Angular v4

A few months ago, I was working on an Angular application for my company project. At that time, I faced a problem with configuring Angular module in the application. After some time, I found a very simple solution. So today, I am going to explain how to use multiple modules. I am sure you will face this type of problem if you are a beginner in Angular 4 and want to develop an e-commerce or any other type of application. So, first of all, read this article because a module is the backbone of Angular applications.
 
If you are a beginner to Angular, just go through the given articles.
So now, you need to follow some simple steps to use multiple modules in an Angular application. Create a simple application using Angular CLI. If you are going to use Angular for the first time, click here. I am going to create an application which contains three modules: App, Employee, Admin, Home.
 
 

In this image, you can see I have created an app with three modules. I think we can understand it very easily after running the command.

 

In the above image, we can see that inside src=>app, Admin, Employee, Home, Login four folder are available. Each folder contains a file like this.
  • home.module.ts
  • home.route.ts
  • home.component.ts
  • home.component.html 
So, go to your app folder and use the given code as per the given file. Create src=>app=>Home=>home.module.ts.
 
src=>app=>Home=>home.module.ts 
  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3. import { RouterModule, Routes } from '@angular/router';  
  4. import { HomeComponent } from './home.component';  
  5. const routes: Routes = [  
  6.     { path: 'Home', component: HomeComponent },  
  7. ];  
  8. @NgModule({  
  9.     declarations: [  
  10.         HomeComponent  
  11.     ],  
  12.     imports: [  
  13.         BrowserModule,  
  14.         RouterModule.forRoot(routes)  
  15.     ],  
  16.     providers: [],  
  17.   
  18. })  
  19. export class HomeModule { }  
src=>app=>Home=>home.route.ts For now I am not using this file. If you want just copy the highlighted code and paste inside home.route.ts and import in module.
 
src=>app=>Home=>home.component.ts 
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.   selector: 'home',  
  5.   templateUrl: './home.component.html',   
  6. })  
  7. export class HomeComponent {  
  8.   title = 'Home component ';  
  9. }  
src=>app=>Home=>home.component.html
  1. <h1>  
  2.   Welcome to {{title}}!  
  3. </h1>  
So, we are done with one module, i.e., Home. Now, it's time to register this module in AppModule. As well as, you can create any number of modules by following the above steps but keep in mind that you have to register that inside the app module.
 
Inside the app folder, you can see there are three main files.
  • app.component.ts
  • app.component.html
  • app.module.ts 
Here, no route is configuring because this module is set for bootstrapping, which means it will run at the starting point. Let me explain how to set route for other modules and configure it.
 
src=>app=>app.component.ts
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.   selector: 'app-root',  
  5.   templateUrl: './app.component.html',   
  6. })  
  7. export class AppComponent {  
  8.   title = 'Angular app using Angular CLI by Bikesh Srivastava ';  
  9. }  
src=>app=>app.component.html 
  1. <div class="container" style="height:100%">   
  2.   <nav class="navbar navbar-inverse navbar-toggleable-md  bg-primary">  
  3.   <a class="navbar-brand" href="#">Welcome {{title}}</a>  
  4.   <div  id="navbarNav">  
  5.     <ul class="navbar-nav">  
  6.       <li class="nav-item active">  
  7.         <a class="nav-link" routerLink="/Home">Home</a>  
  8.       </li>        
  9.       <li class="nav-item">  
  10.         <a class="nav-link" routerLink="/Admin">Admin</a>  
  11.       </li>    
  12.        <li class="nav-item">  
  13.         <a class="nav-link" routerLink="/Employee">Employee</a>  
  14.       </li>     
  15.     </ul>  
  16.   </div>  
  17. </nav>  
  18. <div style="margin-top:20px; height:100%">  
  19.   <router-outlet ></router-outlet>   
  20.   </div>  
  21. </div>  
src=>app=>app.module.ts
  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3. import { AppComponent } from './app.component';  
  4. import { RouterModule, Routes ,PreloadAllModules} from '@angular/router';  
  5. import {AdminComponent} from './Admin/admin.component';  
  6. import {EmployeeComponent} from './Employee/emp.component';  
  7. import {HomeComponent} from './Home/home.component';  
  8. import {HomeModule} from './Home/home.module';  
  9. import {EmployeeModule} from './Employee/emp.module';  
  10. import {AdminModule} from './Admin/admin.module';  
  11. import {LogInComponent} from './Login/login.component'  
  12.   
  13. const routes: Routes = [    
  14.   //{path:'',component:LogInComponent},  
  15.   { path: 'Home', loadChildren:()=> System.import('./Home').then((comp: any) => comp.default) },  
  16.   { path: 'Admin', loadChildren:()=> System.import('./Admin').then((comp: any) => comp.default) },  
  17.   { path: 'Employee', loadChildren:()=> System.import('./Employee').then((comp: any) => comp.default) },  
  18. ];  
  19. @NgModule({  
  20.   declarations: [  
  21.     AppComponent, //LogInComponent      
  22.   ],  
  23.   imports: [  
  24.     BrowserModule,  
  25.     HomeModule,  
  26.     EmployeeModule,  
  27.     AdminModule,      
  28.     RouterModule.forRoot(routes, { useHash: false, preloadingStrategy: PreloadAllModules }),  
  29.   ],  
  30.   providers: [],  
  31.   bootstrap: [AppComponent]  
  32. })  
  33. export class AppModule { }  
src=>main.ts
  1. import { enableProdMode } from '@angular/core';  
  2. import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';  
  3.   
  4. import { AppModule } from './app/app.module';  
  5. import { environment } from './environments/environment';  
  6.   
  7. if (environment.production) {  
  8.   enableProdMode();  
  9. }  
  10.   
  11. platformBrowserDynamic().bootstrapModule(AppModule);  
src=>index.html
  1. <!doctype html>  
  2. <html lang="en">  
  3. <head>  
  4.   <meta charset="utf-8">  
  5.   <title>Angular4</title>  
  6.   <base href="/">  
  7.   
  8.   <meta name="viewport" content="width=device-width, initial-scale=1">  
  9.   <link rel="icon" type="image/x-icon" href="favicon.ico">  
  10. </head>  
  11. <body>  
  12.   <app-root></app-root>  
  13. </body>  
  14. </html>  
src=>custom-typings.d.ts  

Don't forget to add this part of file and code inside src folder, otherwise you can't find System.import function.
  1. /* 
  2.  * Custom Type Definitions 
  3.  * When including 3rd party modules you also need to include the type definition for the module 
  4.  * if they don't provide one within the module. You can try to install it with @types 
  5.  
  6. npm install @types/node 
  7. npm install @types/lodash 
  8.  
  9.  * If you can't find the type definition in the registry we can make an ambient/global definition in 
  10.  * this file for now. For example 
  11.  
  12. declare module 'my-module' { 
  13.  export function doesSomething(value: string): string; 
  14. } 
  15.  
  16.  * If you are using a CommonJS module that is using module.exports then you will have to write your 
  17.  * types using export = yourObjectOrFunction with a namespace above it 
  18.  * notice how we have to create a namespace that is equal to the function we're 
  19.  * assigning the export to 
  20.  
  21. declare module 'jwt-decode' { 
  22.   function jwtDecode(token: string): any; 
  23.   namespace jwtDecode {} 
  24.   export = jwtDecode; 
  25. } 
  26.  
  27.  * 
  28.  * If you're prototying and you will fix the types later you can also declare it as type any 
  29.  * 
  30.  
  31. declare var assert: any; 
  32. declare var _: any; 
  33. declare var $: any; 
  34.  
  35.  * 
  36.  * If you're importing a module that uses Node.js modules which are CommonJS you need to import as 
  37.  * in the files such as main.browser.ts or any file within app/ 
  38.  * 
  39.  
  40. import * as _ from 'lodash' 
  41.  
  42.  * You can include your type definitions in this file until you create one for the @types 
  43.  * 
  44.  */  
  45.   
  46. // support NodeJS modules without type definitions  
  47. declare module '*';  
  48.   
  49. /* 
  50. // for legacy tslint etc to understand rename 'modern-lru' with your package 
  51. // then comment out `declare module '*';`. For each new module copy/paste 
  52. // this method of creating an `any` module type definition 
  53. declare module 'modern-lru' { 
  54.   let x: any; 
  55.   export = x; 
  56. } 
  57. */  
  58.   
  59. // Extra variables that live on Global that will be replaced by webpack DefinePlugin  
  60. declare var ENV: string;  
  61. declare var HMR: boolean;  
  62. declare var System: SystemJS;  
  63.   
  64. interface SystemJS {  
  65.   import: (path?: string) => Promise<any>;  
  66. }  
  67.   
  68. interface GlobalEnvironment {  
  69.   ENV: string;  
  70.   HMR: boolean;  
  71.   SystemJS: SystemJS;  
  72.   System: SystemJS;  
  73. }  
  74.   
  75. interface Es6PromiseLoader {  
  76.   (id: string): (exportName?: string) => Promise<any>;  
  77. }  
  78.   
  79. type FactoryEs6PromiseLoader = () => Es6PromiseLoader;  
  80. type FactoryPromise = () => Promise<any>;  
  81.   
  82. type AsyncRoutes = {  
  83.   [component: string]: Es6PromiseLoader |  
  84.                                Function |  
  85.                 FactoryEs6PromiseLoader |  
  86.                          FactoryPromise  
  87. };  
  88.   
  89.   
  90. type IdleCallbacks = Es6PromiseLoader |  
  91.                              Function |  
  92.               FactoryEs6PromiseLoader |  
  93.                        FactoryPromise ;  
  94.   
  95. interface WebpackModule {  
  96.   hot: {  
  97.     data?: any,  
  98.     idle: any,  
  99.     accept(dependencies?: string | string[], callback?: (updatedDependencies?: any) => void): void;  
  100.     decline(deps?: any | string | string[]): void;  
  101.     dispose(callback?: (data?: any) => void): void;  
  102.     addDisposeHandler(callback?: (data?: any) => void): void;  
  103.     removeDisposeHandler(callback?: (data?: any) => void): void;  
  104.     check(autoApply?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;  
  105.     apply(options?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;  
  106.     status(callback?: (status?: string) => void): void | string;  
  107.     removeStatusHandler(callback?: (status?: string) => void): void;  
  108.   };  
  109. }  
  110.   
  111.   
  112. interface WebpackRequire {  
  113.     (id: string): any;  
  114.     (paths: string[], callback: (...modules: any[]) => void): void;  
  115.     ensure(ids: string[], callback: (req: WebpackRequire) => void, chunkName?: string): void;  
  116.     context(directory: string, useSubDirectories?: boolean, regExp?: RegExp): WebpackContext;  
  117. }  
  118.   
  119. interface WebpackContext extends WebpackRequire {  
  120.     keys(): string[];  
  121. }  
  122.   
  123. interface ErrorStackTraceLimit {  
  124.   stackTraceLimit: number;  
  125. }  
  126.   
  127.   
  128. // Extend typings  
  129. interface NodeRequire extends WebpackRequire {}  
  130. interface ErrorConstructor extends ErrorStackTraceLimit {}  
  131. interface NodeRequireFunction extends Es6PromiseLoader  {}  
  132. interface NodeModule extends WebpackModule {}  
  133. interface Global extends GlobalEnvironment  {}  
All set to run the application. If you get any error, just remove node_module folder and use "npm install" command on terminal. Let's run the application using "npm start".  The output will looks like this.

 
Click on any one of the links and see the output. 
 
Sometimes, you can get an error related to port number. Don't worry about that. Just copy the given code and paste inside angular-cli.json
  1. "defaults": {  
  2.     "serve": {  
  3.       "port": 2500  
  4.     },  
  5.     "styleExt""css",  
  6.     "component": {}  
  7.   }  
Conclusion

In this article, I have explained how to make Angular app communicate with multiple modules; parent to child, and child to parent. In this application, we have found a simple way to load another module. Thereafter, the module will load all components and components will render the HTML according to the selector.