×
☰ See All Chapters

Module in Angular - @NgModule

Angular class annotated with @NgModule help to organize an application into cohesive blocks of functionalities and extend it with capabilities from external libraries. Take for example, you have 10 components in your project, and that translates into 10 files. Now, given that you have another two new components – namely ComponentA and ComponentB. These 2 components depend on the 10 components we just described above.

Prior to RC 5, this is how you do it.

// a.component.ts

// import all 10 components here

import { No1Component, No2Component, ... } from './components';

 

@Component({

    selector: 'a-cmp',

    templateUrl: 'a-cmp.component.html',

    directives: [No1Component, No2Component, ...] // inject all 10 components here

})

export class AComponent {

}

Then, repeat the same process for ComponentB. Now, if we were to create many more components that behave like ComponentA and ComponentB, it surely will become cumbersome to keep including these 10 components into every other component. It is certainly not a fun thing to do! However, you create a grouped constant with all 10 components imported and then export this one constant to use by other components.  Let’s look at a more refactored code:

// groupOfComponents.ts

// import all 10 components here

import { No1Component, No2Component, ... } from './components';

 

// export an array of all 10 components

export const groupedComponents = [No1Component, No2Component, ...];

Then change your ComponentA code, to import the grouped constant to ComponentA

// a.component.ts

import { groupedComponents } from './barrel';

 

@Component({

    selector: 'a-cmp',

    templateUrl: 'a-cmp.component.html',

    directives: [groupedComponents] // inject all grouped components here

})

export class AComponent {

}

 

 

The code is earlier to include components, but now you still have to include groupedComponents in every component that you need it. The solution for this is @NgModule. With @NgModule, what you need to do is this

// a.component.ts

 

@Component({

    selector: 'a-cmp',

    templateUrl: 'a-cmp.component.html'

    // no more directives, no more importing component to component

})

export class AComponent {

}

By declaring components, directives, pipes under @NgModule, You no need to import any components, directives, pipes to any of your components. All the components, directives, pipes declared under @NgModule will be available throughout the components under the module.

Every Angular app has at least one module, the root module, conventionally named AppModule.

Here is how a typical AppModule will look like:

// app.module.ts

 

@NgModule({

    declarations: [ // put all your components / directives / pipes here

        AppComponent, // the root component

        No1Component, No2Component, ... // e.g. put all 10 components here

        AComponent, BComponent, // e.g. put component A and B here

        NiceDirective,

        AwesomePipe,

    ],

    imports: [ // put all your modules here

        BrowserModule, // Angular 2 out of the box modules

        TranslateModule, // some third party modules / libraries

    ],

    providers: [ // put all your services here

        AwesomeService,

    ],

    bootstrap: [ // The main components to be bootstrapped, normally one only

        AppComponent

    ]

})

export class AppModule { }

You should bootstrap your application using this app.module.ts.

// main.ts

 

...

platformBrowserDynamic().bootstrapModule(AppModule);

...

 

@NgModule fields

The @NgModule decorator has four fields:

Field

Description

declarations

Declare the components, directives, and pipes contained in the application.

imports

Declare the components required by the application

providers

Declare the support classes contained in the application

bootstrap

Declare the component that launches the application

The difference between import statements and the imports array in @NgModule is every typescript file used by the current typescript file should be imported by import statement whereas imports array of @NgModule only contains the features required by the application. For the most part, these are provided by the Angular framework. At minimum, this array should contain BrowserModule.

The support classes like services, controllers which are not annotated with any angular annotations but just supporting classes should be declared under providers array. These supporting classes don't affect the user interface directly, but provide data and methods that can be accessed by components, directives, and other Angular classes.

The last array, bootstrap, identifies the application's primary component. This is the component that launches the application. In every application I've encountered, this array only contains one element. The bootstrapping process is made possible by the BrowserModule. BrowserModule is the angular provided class.


All Chapters
Author