Angular CLI - Getting Started

Posted by: Ravi Kiran , on 1/2/2018, in Category AngularJS
Views: 17100
Abstract: Learn how to install Angular CLI, create an Angular project and run different tasks provided by Angular CLI on it.This tutorial also explains the importance of a generator to build Angular applications.

Angular is one of the most widely used front-end frameworks. It is used by many companies, individuals and open source developers to build web applications.

Introducing Angular CLI

As many of you would know, building a modern web application using a front-end framework like Angular is no more as simple as developing few html pages and showing them on the browser. To work with modern JavaScript frameworks, you now need an environment to be set on the machine, as well as an environment for the application inside the folder that has to contain the code.

Are you keeping up with new developer technologies? Advance your IT career with our Free Developer magazines covering Angular, React, .NET Core, MVC, Azure and more. Subscribe to this magazine for FREE and download all previous, current and upcoming editions.

The following list shows the required tools to build an Angular application at a higher level:

  • The system to be used for development should have Node.js installed on it. Node.js is a server platform that supports building web servers using JavaScript. It is also widely used as a platform to build web applications, as it is very easy to spin up a server and start it instantly on Node.js.
  • A Node.js based package manager like npm or yarn is needed to install the libraries to be used in the application.
  • The application needs a setup to install a set of required packages containing the library files, tools to compile the TypeScript code, bundle the files together, run unit tests, start a web server and build files to deploy the application. While setting up these tasks has become easier with tools like Grunt, Gulp and Webpack, one still needs to spend time in writing the scripts for these tasks in every new project.

The third point of the above list takes a lot of time and effort.

To reduce this pain, the Angular team created Angular CLI. Angular CLI is a generator that makes the process of building an Angular application easier.

This article will make you comfortable with using Angular CLI by creating a simple Angular application.

Angular CLI Installation

As noted earlier, Node.js has to be installed on the system to be used for development. The installer for Node.js can be downloaded from the official site. The installer adds Node.js and the package manager npm to the system.

Angular CLI is a package to be installed globally using npm. To install it, open a command prompt with administrative privileges and run the following command:

> npm install -g @angular/cli

This command installs the command line tool required to build an application using Angular CLI. To check if the installation is successful, you can check the version of Angular CLI using the following command:

> ng -v

Creating a Project using Angular CLI

Now that our system is ready to develop an Angular application, it would be good to explore the essential features of Angular CLI by building a sample.

Open a command prompt, move to a location where you want to save the project and run the following command:

> ng new SampleApp

This command runs for a few minutes and performs the following tasks:

  • Creates a new folder named after the project
  • Adds a number of files and folders containing the files to be used to run the application
  • Adds a bare minimal Angular application to the folder
  • Installs the npm packages
  • Enables git in the project

The following screenshot shows the structure of the project on VS Code:

angular-cli-project-structure

Figure 1 - Project structure

The following listing explains the files and folders shown in figure 1:

  • e2e: This folder has to be used to add end-to-end tests. These tests have to be written using protractor. This folder contains some sample tests for the application added by the Angular CLI
  • src: This folder contains the source files, spec files, styles, TypeScript configuration files and the index.html file. We will spend most of our time in this folder, as all of the code we write goes into it
  • .angular-cli.json: This file contains the configuration to be used by Angular CLI. It includes the HTML file to start the application, the first TypeScript file to be loaded while running the application, paths of the TypeScript configuration files to be used for source files and unit test files
  • .editorconfig: This file contains configuration for the editor. The editors used to work on the application read this file and use these settings while creating new files and editing files
  • karma.conf.js: This file is the input to the karma test runner. The test runner learns everything about running the tests using the configuration added in this file
  • package.json: This file contains the list of dependencies to be installed to develop and deploy the application and a set of scripts to perform operations like starting the application, running tests and generating files for deployment
  • protractor.conf.js: This file is used to run end-to-end tests using protractor
  • README.md: This file contains documentation of the project in markdown format. By default, it contains the basic commands to be used to work with Angular CLI. It can be modified it to describe the project
  • tsconfig.json: This file contains the configuration to be used by the TypeScript compiler. The files tsconfig.app.json and tsconfig.spec.json present in the src folder extend this file to define the configuration to be used to compile the source files and the spec files
  • tslint.json: This file contains a set of rules to check quality of the TypeScript code written in the application

Note: npm is the default package manager in Angular CLI. If you are a fan of ‘yarn’ and want to use it, you can ask Angular CLI to globally switch to yarn by running the following command: ng set –global packageManager=yarn

Now the newly created project has just everything you need in an Angular application, you don’t need to set up any tooling by yourself.

A Simpler Setup for an Angular app

While the setup we just saw in Figure 1 is the most comprehensive setup for an Angular application, sometimes the need is just to have a simpler setup for the application.

For example, to write some simple demos, one doesn’t require everything in this setup. Using the ng new command with minimal flag creates a simpler application structure. Following is the command:

> ng new SampleApp –minimal

The following screenshot shows the folder structure of the project created using the above command:

minimal-angular-cli

Figure 2 - Minimal Project Structure

On comparing Figure 2 with Figure 1, you will see that the project created with the minimal flag has less number of files in it. The ng new command supports a number of other flags. The following list explains some of the useful flags:

  • routing: Adds a routing module to the application
  • style: To customize the type of styles to be used in the application. By default, it uses CSS. This flag can be used to change the type of styles to LESS, SCSS or Stylus. The CLI installs the ­corresponding webpack plugins and generates the Angular CLI config based on the style type specified
  • verbose: This flag adds details to the output of Angular CLI commands that will be used in the application

To run the application generated above, run the following command:

> ng serve

This command starts a dev server on port 4200. Open a browser and change the URL to http://localhost:4200 to view the application. The browser would render a page similar to the following:

angular-sample-app

Figure 3 - Initial page

Understanding the Sample Generated

The page shown on the browser in Figure 3 is generated from the index.html file located in the app folder. The body of this page contains the component app-root, this component is used to bootstrap the application.

<body>
  <app-root></app-root>
</body>
  

The component app-root is defined in the file src/app/app.component.ts. This component doesn’t have much code. The code in this file sets the CSS and template to the component. The following snippet shows the code:

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

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

The app-root component is registered in the module AppModule in the file src/app/app.module.ts. As this component is used to start the application, it is set as the bootstrap component in the module. The following snippet shows code of the module:

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 { }

The src/main.ts file in the app folder bootstraps the application using AppModule. This file also checks for the environment and runs the application in production mode, if needed. The following snippet shows the code in this file:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));

The call to enableProdMode function in the if condition in the above snippet optimizes the code for production build. The resulting code won’t be friendly enough for debugging.

Adding Some Code

Angular CLI provides a number of commands to generate the code. It is a good idea to explore it by adding some code to the application. Before adding any code, let’s add Bootstrap to the application. Run the following command to install bootstrap:

> npm install bootstrap --save

To use it in the application, it has to be configured in the .angular-cli.json file. Open this file and modify the styles property of the application as shown in the following snippet:

"styles": [
  "styles.css",
  "../node_modules/bootstrap/dist/css/bootstrap.css"
]

As you see, the above snippet adds path of the Bootstrap’s CSS file to the styles of the application. This makes the styles defined in this file available to the application and this file is included in the bundle created for the application.

Let’s add a new component to the application. This component will list a few features of Angular and display a short description when a feature is clicked. The following command generates this component:

> ng generate component angular-features

Angular CLI has shorter versions of these commands as well. The same command can be re-written as:

> ng g c angular-features

This command adds a new folder to the application and adds the component class, CSS file, template file and a unit test file for the component. The following image shows the folder generated:

angular-component-structure

Figure – 4 Structure of component generated

As every feature will have a few properties, it is better to create an interface to hold the structure of the features. The following command adds the AngularFeature interface to the src/app folder of the application:

> ng g i AngularFeature

Open the file angular-feature.ts and replace the code with the following:

export interface AngularFeature {
  name: string;
  description: string;
  isExpanded: boolean;
}

Open the file angular-features.component.ts and place the following code in this file:

import { Component, OnInit } from '@angular/core';
import { AngularFeature } from '../angular-feature';

@Component({
  selector: 'app-angular-features',
  templateUrl: './angular-features.component.html',
  styleUrls: ['./angular-features.component.css']
})
export class AngularFeaturesComponent implements OnInit {
  ngFeatures: AngularFeature[] = [];

  constructor() { }

  ngOnInit() {
    this.ngFeatures = [
      {
        name: 'Components',
        description: `Components are used to create custom HTML elements. The elements are independent and
         self sufficient pieces of UI that can be reused in any template. Components also help in making the 
         template more readable.`,
        isExpanded: false
      },
      {
        name: 'Directives',
        description: `Directives are used to extend the behavior of the HTML elements. They can be added to 
        a target HTML element to change the behavior of the element based on the business need.`,
        isExpanded: false
      },
      {
        name: 'Pipes',
        description: `Pipes are used to format the data before displaying it on the page. Any data bound on the 
        UI may need some transformation like formatting date, displaying currency symbol or any custom transformation.
         All of these transformations can be done using pipes.`,
        isExpanded: false
      },
      {
        name: 'Services',
        description: `Services are used to handle any non UI logic. They can be injected into any component, directive
         or other services where the piece of logic is required.`,
        isExpanded: false
      }
    ];
  }
}

The component in the above snippet has an array with a few of the features of Angular, a short description of these features and a boolean flag to show or hide the description on the page.

The template of the component has to be modified to show the features in a list. Open the file angular-features.component.html and place the following code in it:

<div>
  <ul>
    <li *ngFor="let feature of ngFeatures">
      <a (click)="feature.isExpanded=!feature.isExpanded">{{feature.name}}</a>
      <div *ngIf="feature.isExpanded">{{feature.description}}</div>
    </li>
  </ul>
</div>

The above snippet a couple of Angular directives and bindings; they are explained below:

  • ngFor - It is a directive used to repeat over a list of items in a collection
  • ngIf - It is a directive that helps in adding an element to the page or removing an element from the page depending on the condition
  • (click): The parentheses around click indicates that this event is bound to a method in the component. The assigned method is called whenever the click event is triggered by the browser on the element
  • {{}} (interpolation): The double-curly braced expression is used to bind the values on the page. It is a one-way binding. The binding gets automatically updated whenever there is a change in the value

These concepts will be covered in detail in future posts.

The angular-features component has to be used in the app-root component. Open the app.component.html file and modify it as shown below:

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!
  </h1>
</div>
<h2>Here are some features of Angular: </h2>
<app-angular-features></app-angular-features>

Run the application after saving the changes made. You should see a page similar to the following image:

modified-app

Figure 5 – Modified application

Click on an entry in the list and you will see the description. Click again on the same entry to hide the description.

Separating data from the component

Now let’s add a service to separate the data from the component. This will make the component focused on what it has to do and also make the data accessible to any other components in the application. Run the following command to generate the service:

> ng g s ngfeatures --module app.module

This command adds a new service and adds it to the module. Without the module flag, the service won’t be added to the module, we would need to register it manually.

Open the file ngfeatures.service.ts and add the following code to it:

import { Injectable } from '@angular/core';
import { AngularFeature } from './angular-feature';

@Injectable()
export class NgfeaturesService {
  private ngFeatures: AngularFeature[];

  constructor() {
    this.ngFeatures = [
      {
        name: 'Components',
        description: `Components are used to create custom HTML elements. The elements are independent and
         self sufficient pieces of UI that can be reused in any template. Components also help in making the 
         template more readable.`,
        isExpanded: false
      },
      {
        name: 'Directives',
        description: `Directives are used to extend the behavior of the HTML elements. They can be added to 
        a target HTML element to change the behavior of the element based on the business need.`,
        isExpanded: false
      },
      {
        name: 'Pipes',
        description: `Pipes are used to format the data before displaying it on the page. Any data bound on the 
        UI may need some transformation like formatting date, displaying currency symbol or any custom transformation.
         All of these transformations can be done using pipes.`,
        isExpanded: false
      },
      {
        name: 'Services',
        description: `Services are used to handle any non UI logic. They can be injected into any component, directive
         or other services where the piece of logic is required.`,
        isExpanded: false
      }
    ];
  }

  public get NgFeatures() : any {
    return this.ngFeatures;
  }
}

The above service has a private member, ngFeatures. This property holds the array of Angular features. It is assigned with the value in the constructor of the service class. The public property NgFeatures provides read only access to this array to the code blocks outside this service.

The angular-features component has to be modified to use this service. Modify it as shown in the following snippet:

import { Component, OnInit } from '@angular/core';
import { AngularFeature } from '../angular-feature';
import { NgfeaturesService } from '../ngfeatures.service';

@Component({
  selector: 'app-angular-features',
  templateUrl: './angular-features.component.html',
  styleUrls: ['./angular-features.component.css']
})
export class AngularFeaturesComponent implements OnInit {
  ngFeatures: AngularFeature[] = [];

  constructor(private ngfeaturesSvc: NgfeaturesService) { }

  ngOnInit() {
    this.ngFeatures = this.ngfeaturesSvc.NgFeatures;
  }
}

The application would now produce the same output as it did earlier.

Serving the Angular Application

Till now, the application was executed using the ng serve command. As stated earlier, it is the easiest way and most of the Angular developers use it every day.

Angular CLI provides a few options to control the way the application is served. To open the browser automatically as soon as the command runs, it has to be supplied with the open option. The command is shown below:

> ng serve --open

or

> ng serve -o

Say, someone is running an Angular CLI application and wants to run one more without killing the first one. Then the second application should use a different port, as 4200 is already in use by the first application. A different port number can be passed to the ng serve command using the port option, as shown below:

> ng serve --port 4201

or

> ng serve -p 4201

If an application would run over HTTPS in production, the developers should ideally run it using SSL on local as well. ng serve can be supplied with the ssl option to run it using HTTPS. The following command shows this:

> ng serve --ssl

Checking tslint Errors

The tslint.json file added by the Angular CLI contains a number of rules to validate quality of the TypeScript code written in the application. To evaluate the code against these rules, the following command has to be executed:

> ng lint

This command checks all the source files and the unit test files in the application and lists the errors in the console. Following screenshot shows a sample output:

tslint-errors

Figure 6 – tslint errors

Bundling the Angular CLI Application

Once the development is complete, we need to deploy the application. As you would already know, code of the application has to be bundled into a few files to host it on a server. The easiest way to bundle the Angular CLI application is using the following command:

> ng build

This command runs webpack and puts the bundled files in the dist folder in the application. The following screenshot shows the contents of the dist folder:

dist-folder-structure

Figure 7 – Structure of dist folder

This command created a developer friendly version of the bundles. The source maps generated helps in debugging the application on the browser. To create more optimized bundles, the command has to be supplied with the prod option, as shown below:

> ng build --prod

Names of the files generated as a result of the prod option contain a hash in them. Value of the hash changes whenever the contents of the files change. And hence, they help in ignoring the files that are already cached in the browser.

Conclusion

Building an Angular application from scratch is a painful task!

Thankfully, Angular CLI makes this process quite easy with its features and flexibilities. Hope this article got you started with the tool. There is a lot more that can be done with Angular CLI. To explore more options and commands, checkout the wiki.

Download the entire source code of this article (Github).

This article was technically reviewed by Mahesh Sabnis.

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Rabi Kiran (a.k.a. Ravi Kiran) is a developer working on Microsoft Technologies at Hyderabad. These days, he is spending his time on JavaScript frameworks like AngularJS, latest updates to JavaScript in ES6 and ES7, Web Components, Node.js and also on several Microsoft technologies including ASP.NET 5, SignalR and C#. He is an active blogger, an author at SitePoint and at DotNetCurry. He is rewarded with Microsoft MVP (Visual Studio and Dev Tools) and DZone MVB awards for his contribution to the community


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook