In this post we are going to have a look at Angular modules: what they are, and what it’s its utility.

A module is a regular Angular class that takes the @NgModule decorator. In Angular we use modules to organize, and structure our code in the same way other programming languages use packages (Java, C#, Pyhton) or libraries (C).

Our final goal is to organize our code in such a way that related features that can be reused over and over can be grouped together and easily made available for re-utilization. In organizing so our code we aim to reduce its complexity and make it easier to maintain.

So basically to create a module we need to decide which set of components, directives, services belong together, and define which ones we are going to make public (available to other modules).

AppModule: the foundation of our angular app

All Angular application had at least one module. If we created our Angular application using the angular-cli, we should have at least this module: AppModule – created by default. Let’s have a look at it:

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

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

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

We see we starting by creating a regular class:

export class AppModule { }

We decorated it with the NgModule decorator; we see that in the decorator we are defining declarations,importsproviders, and bootstrap.

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
  • Declarations: Here we are going to declare which components, directives, and pipes belong to this module. If we try to use inside the module a component and we do not add it here, it will result in an error in runtime.

When creating a new angular app, angular-cli creates also an almost empty component: AppComponent. So at this point our freshly created angular app, has only this one component  – AppComponent – and it has already been added for us to the declarations array. As we add new components to our module, we should declare them here.

  • Imports: this one is pretty intuitive; here you import the external modules you are going to need in your module. Think of it as the run of the mill import of libraries in any other programming language. For example, in C# this would be akin to do this:
    using System;
    using System.Collections.Generic;
    using Xunit;
    using MyCustomApp.Controllers;
    using MyCustomApp.Models;
    

    Back to the AppModule: we see that at this point it is only importing the BrowserModule. This is an Angular module on top of which we can build Angular applications.As we develop our AppModule we may need the functionality provided by other Angular modules, any third party modules, or even our own custom modules. In fact if we are building a module now, it is because we expect to use it – this is to import it – somewhere, so it will end up in the imports array of another module in the future.

  • providers: this one is quite similar to declarations we have seen before, but what we declare here are the @Injectables that our module requires: in other words the services. At this moment it is empty because ng-cli creates a default component when creating a new application, but it does not create any service. All services we create in this module from now on must be declared here.
  • bootstrap: here we are indicating the root component that it is going to start when we launch the application: the point of entry to the application so to say. As said before all Angular application need at least one module: the root module that will bootstrap and launch the application. This module it is usually called AppModule, and it is created by default by ng-cli when creating a new Angular app.

Now, there is another important property in the @NgModule we have not seen yet: exports. We have said at the beginning in this post that in modules we do basically two things:

  • Declare components, directives, services etc we are going to use in the module.
  • Declare which components, directives, etc are we going to make available outside of the module.

So far we have declared all what we are going to use, but out AppModule exports nothing to the world 😦 . This is to be expected: we are, after all, watching at the root module of a blank, just created application.

Let’s have a look at a different module, for example at one of the Angular basic modules: CommonModule. This module exports all the basic Angular directives and pipes (you are not calling it directly since it is reexported by our old friend BrowserModule).

@NgModule({
  declarations: [COMMON_DIRECTIVES, COMMON_PIPES],
  exports: [COMMON_DIRECTIVES, COMMON_PIPES],
  providers: [
    {provide: NgLocalization, useClass: NgLocaleLocalization},
  ],
})
export class CommonModule {
}
})

Looking at the code above we notice the following:

    • Absence of bootstrap attribute. Not surprising since this module is not suppose to launch an app.
    • Also not import of external modules, again not surprising since we are looking at the core of Angular.
    • We see that it uses a service: NgLocalization
    • It declares a series of directives and pipes:COMMON_DIRECTIVES, COMMON_PIPES.
      Now if we look further in the code we will see that the COMMON_DIRECTIVES are:

      export const COMMON_DIRECTIVES: Provider[] = [
        NgClass,
        NgComponentOutlet,
        NgForOf,
        NgIf,
        NgTemplateOutlet,
        NgStyle,
        NgSwitch,
        NgSwitchCase,
        NgSwitchDefault,
        NgPlural,
        NgPluralCase,
      ];
      

      And here we have the COMMON_PIPES:

      export const COMMON_PIPES = [
        AsyncPipe,
        UpperCasePipe,
        LowerCasePipe,
        JsonPipe,
        SlicePipe,
        DecimalPipe,
        PercentPipe,
        TitleCasePipe,
        CurrencyPipe,
        DatePipe,
        I18nPluralPipe,
        I18nSelectPipe,
        KeyValuePipe,
      ];
      

Meaning that in the CommonModule is defined such basic, everyday Angular stuff like NgIf, NgClass, UpperCasePipe, etc

  • And finally it exports this same COMMON_DIRECTIVES, COMMON_PIPES. Meaning that the directives coded in this module are made public so that other modules can use them. And in this way we are able to use NgIf and co. in our custom Angular applications.

That’s all for today. Thank you for reading 🙂