Introduction to Modules in Angular

quiz
Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Overview

Angular Framework is strictly modularized by design, you don't have to explicitly define your own standards to segregate the Angular Code. Angular has its own thing for defining modules, which is NgModule. NgModule is the most important part of the Angular application. They help to create separate modules, these modules can be loaded on demand by the technique of router lazy loading. We will look at this lazy loading technique in the next chapter.

Scope

In this chapter, we will look at

  • What is a module in Angular?
  • How to create your own NgModule?
  • What various metadata options can be passed inside the NgModule decorator?
  • How to define and load feature modules

Introduction

Every Angular application has at least contains one NgModule class, the root module in angular known as AppModule, and resides in app.module.ts. The application launched by bootstrapping the root NgModule(AppModule). Most applications would have much more NgModule aka feature modules. The root NgModule includes all child NgModules in a hierarchy of any depth.

A Basic Use of Modules

  • An NgModule is a class marked by the @NgModule decorator
  • NgModule is a collection of directives, components, pipes, services, other dependency modules, providers, etc.
  • It creates a logical boundary for dependencies resolution.
  • It helps to organize related things together.
  • It can control what can be exposed from @NgModule.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

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

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  bootstrap: [AppComponent],
  providers: [],
  exports: [],
})
export class AppModule { }

NgModule Metadata

You can pass configuration in metadata@NgModule decorator

optionDescription
declarationsThings used on HTML belonging to this NgModule like components, directives, and pipes
exportsThe subset of declarations that should be reusable in the component templates of other NgModules
importsOther modules whose exported (components, directives, pipes) classes and services are needed in this NgModule.
providersCreators of services that this NgModule contributes to the global collection of services
bootstrapThe main application view (entry point), called a root component, hosts all other application views. Only the root NgModule should set the bootstrap property

Declarations Array

  • declarations array consist of classes that are used on HTML from the NgModule
    • Component
    • Directive
    • Pipe
  • Without declaring these classes inside the declarations array, they can not be used on HTML.
@NgModule({
  imports: [...],
  // all components, directives, and pipes
  declarations: [
    MyComponent,
    MyDirective,
    MyPipe
  ],
  bootstrap: [...],
  providers: [...],
})
export class FeatureModule {
}

Providers Array

  • It contains
    • Configurable dependencies
    • Providers / Services
@NgModule({
  imports: [...],
  declarations: [...],
  bootstrap: [...],
  // providers are here
  providers: [
    MyService,
    {
      provide: MyToken,
      useValue: config,
    },
  ],
})
export class FeatureModule {
}

Imports Array

  • Imports other @angular NgModule where the current module is dependent on
  • From imported NgModule we can use exported classes on current module component templates
  • Providers (services) will also be available for injection and use.
  • To use 3rd party library features, include respective NgModule in the desired module, wherever you wanted to use library features.
@NgModule({
  // import other NgModule's here
  imports: [
    CommonModule,
    RouterModule.forChild([]),
  ],
  declarations: [...],
  bootstrap: [...],
  providers: [...],
})
export class FeatureModule {
}

Exports Array

  • export NgModules, components, pipes, and directives, that can be used by importer NgModule.
  • To export components/pipes/directives, they should also be a part of the declarations array.
  • If we don't export the aforementioned classes, you would see an error in the console for eg. 'my-component' is not a known element
@NgModule({
  imports: [...],
  declarations: [
    MyComponent,
    MyDirectivbe,
    MyPipe,
  ],
  bootstrap: [...],
  providers: [...],
  // exports classes here
  exports: [
    MyComponent,
    MyDirectivbe,
    MyPipe,
  ],
})
export class FeatureModule {
}

Bootstrap

  • Mention which component should be the root of an application.
  • Ideally, there should be a single root component per application.
  • But there could be cases, that you may add multiple root components in the bootstrap option.
@NgModule({
  declarations: [...],
  imports: [...],
  // bootstrap component(s) here
  bootstrap: [AppComponent],
  providers: [],
})
export class AppModule { }

NgModules and Components

NgModulesComponents
It collates different building blocks of an application togetherComponent consists of the template and its associated class
It has providers array to resolve dependenciesComponent instance has change detector for resolving dependencies
It forms injector tree for lazily loaded moduleComponents create view DOM tree for nested components
NgModule providers are lookup after components providersChange detector resolve dependency on component level, then NgModule level

NgModules and JavaScript Modules

NgModulesJavascript Modules
Angular specific constructJS modules are part of the browser itself
It combines different pieces of Angular Framework under a single blockIt can import or export function/variables/classes
It helps to divide an application into small blocksES module help to modularize code
Encapsulates code to hide implementation detailshelps to create a boundaries between different parts of an application
Accepts metadata configurationIt does not accept any metadata configuration object
helps to keep the Separation of concernsAvoid leaking code to the global namespace

Angular Module Example

Below is an example of a Simple NgModule

@NgModule({
  imports: [CommonModule]
  declarations: [SimpleComponent],
  providers: [],
})
export class SimpleModule {
}

Create the Application

You can run below command in command line / terminal. This helps to create a brand new angular application.

ng new employee-management --prefix=em
  • ng new - helps to create a new angular project
  • employee-management - project and folder name
  • --prefix=em - is selector prefix used when new components/directives are generated.

Routing Module

  • When creating an app, it would ask to enable routing, just say "YES" there.
  • It automatically adds AppRoutingModule
  • It would have empty routes registered with RouterModule's forRoot method.
  • Add fallback route to routes array using wildcard (**) check
const routes: Routes = [
  {path: '**', redirectTo: '/home'},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Root Module

  • AppRoutingModule is already imported in AppModule imports arrray
@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule { }

Creating a Module

Again, you can use CLI for generating NgModule.

Generate NgModule Using CLI

ng generate module home
# OR
ng g m home

It generates HomeModule inside home folder

home.module.ts


@NgModule({
  imports: [
    CommonModule
  ],
  declarations: []
})
export class HomeModule { }

Components

Create Home Component

ng generate component home --module=home.module
# OR
ng g c home --module=home.module
  • ng g c home - Create a HomeComponent
  • --module=home.module - Declare HomeComponent under declartions of HomeModule

Folder Structure

Folder Structure

You can additionally add routing of HomeModule, register home path against HomeComponent with the help of RouterModule's forChild method.

home.module.ts

@NgModule({
  imports: [
    CommonModule
  ],
  // HomeComponent declaration automatically added here
  declarations: [HomeComponent]
  // imported module below
  RouterModule.forChild([
    {path: 'home', component: HomeComponent},
  ])
})
export class HomeModule { }

Using HomeModule in AppModule

  • Import HomeModule inside a Root Module i.e. AppModule
  • This way we extended the RootModule with the feature NgModule.
@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    // imported module below
    HomeModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule { }

Create NgModule and Component along with Routing Using CLI

We've already said this multiple times, Angular CLI is helping developers by automating most of the stuff. There should be something to simplify these many file creation. Yo! that's possible, you would just need to fire the below command to generate the scaffold files.

ng generate module home --route home --module app.module

Let's try to understand the above command in parts

  • ng generate module home - Generate home.module.ts
  • --route home - Create a HomeComponent
  • --route home - Create route configuration for the HomeComponent, and mentions it in imports of a home.module.ts
  • --module app.module - Include the HomeModule inside AppModule.

Changes in app.component.html

Add placeholder for router, to keep watch on URL and render a matched view inside it.

<router-outlet></router-outlet>

Angular Libraries

ModuleDescription
CommonModule / BrowserModuleMost of the common components, directives, services, and pipes
RouterModuleRouting related Component, directives and services are imported from here
HttpClientModuleAPI for making HTTP calls
FormsModuleFor template-driven form
ReactiveFormsModuleFor model driven form
ElementModuleuse methods to create web components from it
i18nModuleUse for i18n or localization

Bootstrapping an Application

Application has to be bootstrap by calling bootstrapModule method, which accepts the root module in angular (AppModule) from main.ts.

platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

Conclusion

  • What is module in angular?
  • How to create a NgModule?
  • How feature module created and imported?
  • Difference between NgModule vs EsModule.
  • Various metadata options exist for the NgModule metadata decorator.
Free Courses by top Scaler instructors