Blog

- November 04, 2016

A few months ago when Angular 2 went into beta, we published an article describing how to implement a front-end application interacting with a Web service. Angular 2 recently moved into a final version with some additional changes.

In this article, we will provide an update to the initial article and focus on the new features to be able to implement an Angular 2 application that leverages a Web API for its data. Let’s start by re-introducing the use case.

Use case

We will use a Web API generated from the quickstart wizard feature of APISpark. It allows us to create an example API, based around a set of companies and contacts, in a matter of seconds.

angular2-api

We will then implement a single page application to manage the API through a Web user interface. Our application will be organized into two distinct parts: one for contacts and one for companies.

The following figure describes all the parts of your application and the built-in objects that we will use.

use-case

Getting started

The first step consists of initializing the project. Angular 2 doesn’t require any module manager and build system. For example, the documentation describes the use of the typescript compiler (tsc) and SystemJS for modules but we are free to use something else, for example the popular tool Webpack.

Another approach is to use the angular-cli tool that allows us to very quickly initialize the project and its build. It’s particularly convenient to set up a development environment with live reload and then build the application for production. Since its latest versions, it relies on Webpack and is particularly efficient.

We will use it for our project. After having installed it using the command npm install angular-cli@webpack, we can leverage it with command line to generate a fake project:

$ ng new angular2-apispark

The skeleton of the project is created and we can start it by using the following command:

$ ng serve

The application is started on the port 4200 and can be reached at the address http://localhost:4200/.

Angular CLI natively supports live reload. That means when the application code is updated, the tool automatically detects it, packages it with Webpack and reloads the page in the browser. This approach is very efficient to develop such applications.

Exploring the project structure

Now we have a very simple application generated, let’s explore its structure. The first elements are related to the project itself and correspond to the configuration of dependencies (package.json), of testing (karma.conf.js and protractor.conf.js) and editors (.editorconfig and tslint.json).

structure1

The source of the application is located under the src folder. We will find directly under this folder the main HTML file (index.html) and entry point for Angular 2 (main.ts). Other files are related to TypeScript for transpilation (tsconfig.json and typings.d.ts). The code of our application is located within the app subfolder.

structure2

Let’s start with modules.

Modules

The most obvious difference between the previous application based on the beta version is the NgModule feature. NgModule provides a different way to bootstrap the application and configure your components.

Modules aren’t a new feature for Angular developers since Angular 1 supports them. This feature was reintroduced in Angular with the version 2.0 RC5.

A module corresponds to a class decorated with @NgModule.

The following lists the main supported attributes at this level:

  • declarations: lists all the custom components and directives that can be used within the module.
  • imports: defines the imported modules.
  • providers: specifies the list of providers usable within the whole module
  • bootstrap: defines the declared components to bootstrap the application

Here is a sample of use.

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

@NgModule({
  declarations: [
    (...)
  ],
  imports: [
    (...)
  ],
  providers: [
    (...)
  ],
  bootstrap: [
    (...)
  ]
})
export class SomeModule { }

To bootstrap our application, simply bootstrap the our main module of the application using the platformBrowserDynamic function, as described below.

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/';

platformBrowserDynamic().bootstrapModule(AppModule);

Angular 2 will have a look at the components defined in the bootstrap attribute and will apply them in the main HTML file according to their selectors.

We only use one module for our application.

Components

Not much has changed at this level. The main thing to note is that we no longer need to specify all the components and directives we want to use at this level.

Previously we had to leverage the directives attribute:

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

@Component({
  selector: 'app-root',
  template: `
    <other-component></other-component>
  `,
  directives: [ OtherComponent ]
})
export class AppComponent {
  (...)
}

With the final version, no more directives attribute is needed in the Component decorator but we need to add them into the declarations attribute of the module where they fit.

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

@Component({
  selector: 'app-root',
  template: `
    <other-component></other-component>
  `
})
export class AppComponent {
  (...)
}

@NgModule({
  declarations: [
    AppComponent, OtherComponent
  ],
  bootstrap: [
    (...)
  ]
})
export class SomeModule { }

Note also that it’s now possible to use relative paths within templateUrl and styleUrls attributes:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  (...)
}

Routes

There were a lot of changes and deprecations during the beta and RC phases. Now routes must be configured outside components as modules. The approach has entirely changed from what it used to be, but it’s much easier and more flexible to use.

It comes with a set of new features:

  • Routes can now be defined as a tree
  • Protect routes with guards
  • A support for resolve was added

Defining a module with routes is simple and based on the RouterModule class. We can note the use of the forChild method to configure the array of routes. This module can be then imported into the module that provides the ElementListComponent and ElementDetailComponent components.

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { ElementListComponent }    from './element-list.component';
import { ElementDetailComponent }  from './element-detail.component';

@NgModule({
  imports: [
    RouterModule.forChild([
      { path: 'elements,  component: ElementListComponent },
      { path: elements/:id', component: ElementDetailComponent }
    ])
  ],
  exports: [
    RouterModule
  ]
})
export class ElementRoutingModule { }

Now we have described the new features of Angular 2, it’s time to implement the application that interacts with our backend using HTTP.

Configuring the additional supports

As underlined previously, Angular 2 relies now on modules. To be able to use routing, forms and HTTP support, we need to import the corresponding modules into the application one. This can be done into the importsattribute of the NgModule decorator.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

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

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

For our needs, the following features modules are imported:

  • BrowserModule: to be able to use built-in directives
  • FormsModule: for the form support of Angular 2
  • HttpModule: to interact with a backend using HTTP
  • RouterModule: to organize applications using routes

This way, our application module will be correctly configured. We no longer need to include the directives we want to use at the level of components or associated providers. They are all included and registered based on imports.

To provide an efficient Web UI to our application, we will use Material Design. First, install the Material integration for Angular 2.

$ npm install @angular/material --save

To make it available within our application, simply import it.

(...)
import { MaterialModule } from '@angular/material';

@NgModule({
  (...)
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule,
    MaterialModule.forRoot()
  ],
  (...)
})
export class AppModule { }

We are now ready to implement our application processing. We will see in the next part of the article how to organize the application processing, interact with the Web API and interconnect everything together.

CTA_free trial_3