Red Green Repeat Adventures of a Spec Driven Junkie

Learning Angular: Modules

I am sharing the continuation of my journey into Learning Angular.

I will continue from the ending of my last article and look into why Angular CLI makes changes to the app.module.ts file when creating a component by trying to use a manually created component.

You will gain an understanding of the connection between components and the module system. I will go over quickly the anatomy of the module file.

This article will take you less than four minutes to read.

Hans Memling - Tommaso di Folco Portinari Maria Portinari source and more information

Introduction

Making an Angular component is easy, just create a file with proper contents article With expected values. A component and all required contents can be a single file, for example, this src/app/hello-world-manual.component.ts

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

@Component({
  selector: 'hello-world-manual',
  template: '<p>hello world manual component</p>',
  styles: ['p { background-color: red }']
})
export class HelloWorldManualComponent {
}

We can use Angular CLI to automatically generate component for us, even have the same file above using certain options, say:

ng generate component --inline-style --inline-template --spec false

Even with the options, one change Angular CLI makes to app.module.ts:

vagrant@ubuntu-bionic:~/test6$ git diff src/app/app.module.ts
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4be5d1c..73cd31c 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -2,10 +2,12 @@ import { BrowserModule } from '@angular/platform-browser';
 import { NgModule } from '@angular/core';

 import { AppComponent } from './app.component';
+import { HelloWorldComponent } from './hello-world/hello-world.component';

 @NgModule({
   declarations: [
-    AppComponent
+    AppComponent,
+    HelloWorldComponent
   ],
   imports: [
	   BrowserModule,

Why does Angular CLI make additional entries in app.module.ts? What does it have to do with the AppComponent and the HelloWorldComponent?

Use HelloWorldManualComponent

To understand why Angular CLI makes those particular changes to the app.module.ts file, let’s try and use our manually generated HelloWorldManualComponent.

Make sure manual component template has the following entries:

  • selector = ‘hello-world-manual’,
  • template = <p>hello world manual component</p>,

(the file contents will be the same as the above example)

app.component.html Changes

To use the HelloWorldManualComponent, let’s put it in the app.component.html file so the file’s contents are below:

test 6 app
<br>
hello world manual component below<br>
<hello-world-manual></hello-world-manual>

Let Magic Begin

With the HelloWorldManualComponent setup in AppComponent’s template, let’s display results in the browser.

$ ng serve # or if using vagrant, ng serve --host 0.0.0.0

Response from ng serve look good:

vagrant@ubuntu-bionic:~/test6$ ng serve --host 0.0.0.0
** Angular Live Development Server is listening on 0.0.0.0:4200, open your browser on http://localhost:4200/ **

Date: 2019-12-20T14:36:28.064Z
Hash: ecac102f70fdbbab5182
Time: 9900ms
chunk {main} main.js, main.js.map (main) 9.56 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 241 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.22 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 135 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.29 MB [initial] [rendered]
ℹ 「wdm」: Compiled successfully.

The browser displays the following:

Blank Browser Page

That’s not expected, even the test 6 app text doesn’t show up! What’s going on??

What does the page inspector show?

Inspector Results

If we change app.module.ts to the following:

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

import { AppComponent } from './app.component';
import { HelloWorldManualComponent } from './hello-world-manual.component';

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

The web page at localhost:4200 should have the following contents:

Hello World Manual Component Working

What is happening?? To use the hello-world-manual component in the app-component, why does app.module.ts need to import it?

Let’s go over the anatomy of the app.module.ts section:

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

NgModule - Declarations

The following is the declaration section:

  declarations: [
	AppComponent,
	HelloWorldManualComponent
  ],

This defines the components and directives to include in the app.module. Hence, without having HelloWorldManualComponent, using the hello-world-manual component in the app.component would be impossible.

NgModule - Imports

The imports section:

  imports: [
	  BrowserModule,
  ],

In this case, only imports the BrowserModule, that has all the modules to run Angular in a browser.

NgModule - Providers

This section is empty in our case:

  providers: []

To use any services for the app, this is section to declare them.

NgModule - Bootstrap

This section:

  bootstrap: [AppComponent]

Does not refer to the Bootstrap CSS library, it refers to what to include on first start up. (If you do include Boostrap CSS library, this file gets a bit more confusing.)

To use the hello-world-manual component in the index.html file, declare HelloWorldManualComponent here.

Conclusion

After seeing what Angular CLI does differently when generating a component compared to creating the component manually shows the importance of app.module.ts.

The app.module.ts file configures Angular how to compile and inject the application together. It puts the other files required for your app to be functional, also letting you separate out components into smaller and reusable files.