Angular 2 - NgModule and the root module

Angular leverages decorators to help configure ES2015 classes. A decorator is an expression that evaluates to a function that makes it possible to annotate and modify classes at design time. 

Angular has a bunch of decorators that it provides in the framework. Typescript provides support for decorators through its transpiler. The syntax for using a decorator is at the symbol, followed by the decorator name, and then a pair of parentheses. What you put in the parentheses depends upon the decorator. An Angular application starts with an Angular module.

Angular modules help to keep application code organized by blocks of functionality and features. A root module acts as a starting point module for an Angular application. We will begin by creating the root module class in a file named app.module.ts that is in the app folder for the project. 

We need to use a decorator to annotate that class so Angular will know it's an Angular module. To inform Angular that the class code here is intended to be an Angular module, you need to decorate it with the NgModule decorator.

Angular exports the NgModule decorator from its core scoped package. To use the decorator from that package, you need to import it using the ES2015 module loading syntax that TypeScript supports. 

You start with the keyword import, followed by a space and a pair of curly braces. Inside the curly braces, you list the types that you want to import, provided in the below example.  

We want to import the NgModule decorator, so I will put that inside of the curly braces. You can import more than one type from a module by adding a comma after each. 

Now we don't need to do that now but I will cover that in a later lesson. After the curly braces you put a space, and then the from keyword followed by another space. After that, you need to put the module name in the form of a string. 

The ES2015 module loading syntax supports loading from a bare module name or a relative path to a file. 

Angular provides a handful of modules in its platform that it exposes via scoped packages. The NgModule decorator comes from the core scoped package in Angular. So for the string of the module name, you put the module name for the Angular core module in single quotes and you end the import statement with a semi-colon. 

Now that we've imported the NgModule decorator, we can use it. When you use it in code, you prefix it with the symbol, then NgModule and a pair of parentheses. You don't put a semi-colon after this expression because it's not a statement but rather a piece of code that will be applied to the class or, in some cases, the property that it comes before. 

So from here, you need to follow it up with the class definition for the Angular module. 

Since this is going to be our app root module, let's name it AppModule. So we type class, space, AppModule, and follow that up with a pair of curly braces. Since we are building this module in its own file, and will want to import it in another file, we need to provide support for using the module loading syntax. You do this by using the export keyword in front of the class keyword.

The NgModule decorator takes in an object with some known properties to configure the class you decorate as an Angular module. These properties are known as metadata. I'm gonna set this object literal up with some properties here and then I will discuss what each are used for. 

So for the Angular root module, we are making use of the imports, declarations and Bootstrap metadata properties. All of these can be set up as an array. The import property is used to bring in other Angular modules that your module will need.

 The declarations property is used to make components, directives and pipes available to your module that don't come from another module. 

The Bootstrap property is used for a root module and will let Angular know which component or components will be the starting point for the Bootstrap process. 

Basically the entry point for your app code. Let's fill these out with some types. Since we are building a browser based app, we will want to make use of the browser module that the Angular platform has available. 

The browser module contains core directives, pipes and more for working with the DOM and can be found in the platform browser scoped package. So we need an import statement for that. And then we can add the browser module to the array for the import metadata property. 

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

            imports: [
            declarations: [
            bootstrap: [
export class AppModule {}

Our app is going to need a starting component.  The component is going to be named AppComponent and it is going to come from a file named app.component.ts. This file will be located right next to the app.module.ts file. So we can write the import statement for that AppComponent, and instead of loading from a bare module name, we can use a string that represents the path to the file relative to this file. 

That will be a dot, slash, followed by the name of the file without the extension. The extension is not needed due to the way the project is configured for system js module loading. Now that's outside the scope of this course so I won't dive into that in detail. 

But from here we want to add the AppComponent to the declarations property, as it's a component we want made available to this Angular module. Finally, we need to add the AppComponent to the Bootstrap property as well. Since this app module is being used as the root module, Angular will use the AppComponent as a target for bootstrapping the app.