Exploring App Module And App Component In An Ionic 2 App

I recently upgraded all my Ionic 2 tutorials from beta versions to the latest version of Ionic 2 and I noticed that there were some changes regarding the App Module.

This inspired me to dig a little bit deeper into what happens at the start of the application. In this post, we'll have a look at the functionality of both the App Component and the App Module.

App Component

You can think of the App Component as the starting point for your Ionic 2 application. Let's have a look at the app.component.ts from my Build Your First Mobile App With Ionic 2 & Angular 2 series.

import { Component } from '@angular/core';  
import { Platform } from 'ionic-angular';  
import { StatusBar, Splashscreen } from 'ionic-native';

import { HomePage } from '../pages/home/home';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {  
  rootPage = HomePage;

  constructor(platform: Platform) {
    platform.ready().then(() => {
      StatusBar.styleDefault();
      Splashscreen.hide();
    });
  }
}

As you can see, this component defines it's template as app.html and it sets the rootPage for the app to HomePage.

In app.html we see that it uses an Ionic Navigation component that reads the rootPage value, so that on launch of the app, this navigation component will load HomePage.

<ion-nav [root]="rootPage"></ion-nav>  

In the constructor of our App Component, we can do any work that needs to happen on initialization of the app. In this case, there are some calls to Cordova Plugins through Ionic Native.

Now, this App Component is pretty straightforward and easy to understand, but it doesn't have any special powers if you compare it to any other Angular component.

So, how does Angular know that it needs to launch the app with the App Component? This is where the App Module comes in.

App Module

The App Module is an Angular Module (NgModule) that tells Angular what is included in your application and how to compile and launch it.

Let's have a look at the app.module.ts from my Build Your First Mobile App With Ionic 2 & Angular 2 series.

import { NgModule, ErrorHandler } from '@angular/core';  
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';  
import { MyApp } from './app.component';  
import { HomePage } from '../pages/home/home';  
import { DetailsPage } from '../pages/details/details';

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    DetailsPage
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    DetailsPage
  ],
  providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}  

As you can see the App Module only contains metadata in the form of the @NgModule decorator. We'll have a look at the properties of this decorator one-by-one.

declarations

In the declarations section we need to include all components, directives and pipes we create as part of our application. If you don't include them here, you'll get an error when you try to use them in your application because Angular won't be able to recognize them in your code.

imports

In the imports section we see that the IonicModule is imported and that it sets the root app component to MyApp which is the App Component we looked at earlier.

IonicModule contains all the components, directives and services from the Ionic framework and by importing the module here we make these available to our app.

You can import other Angular Modules here that you might want to use in your app. For example, have a look at the app.module.ts of my Beginner's Guide To Using ngrx In An Ionic 2 App tutorial.

In the tutorial app, I'm using the Angular Http service in my GithubService and I was a little bit confused at first that I didn't get an error when using it without explicitly importing the HttpModule in my App Module. As it turns out, IonicModule imports the HttpModule and that means it's automatically imported for our app as well.

Update: the above comment isn't true anymore, you need to explicitly import HttpModule in the App Module if you're using it in your Ionic app.

bootstrap

In the bootstrap section, we configure which components are created at the launch of the application.

Usually, you'll only find one component in this array. In this case, that is the IonicApp component, which is Ionic's root component, which is responsible for loading our MyApp Component.

If you have a look at index.html, you'll see that <ion-app>, the selector for IonicApp, is included in the <body>. On start of the application, Angular will create an instance of IonicApp and insert it in the place of the <ion-app> element.

<!-- Ionic's root component and where the app will load -->  
<ion-app></ion-app>  

entryComponents

In the entryComponents section we define any component that is only loaded by its type. This is the case for all Page components since these are all loaded through the Navigation Controller.

Components that are loaded declaratively (i.e. are referenced in another component's template) don't need to be included in the entryComponents array.

So as you can see we have some duplication where we have to define our Page components in both the declarations and the entryComponents sections. The reason for having this separate entryComponents section is so that Angular can compile a bundle for the app that will only include the components that are actually used within the app.

This process is called tree shaking and it makes the codebase for deployment much smaller. You can read more about how tree shaking works here.

providers

In the providers section we can register services for dependency injection. When you register a service in the App Module, it can be used in all the components in your app.

However, we don't need to include all our services here, we can also decide to register a service only for a specific component in its @Component decorator.

Closing Thoughts

I hope this posts helped you get a better understanding of what is happening in the App Module and how it all hangs together.

The documentation on angular.io is actually really good so I've included a couple of links below for further reading.