A tour of Angular for web developers
Tags: angular, webdev, tutorial
Published: 2020-08-22 08:40:03

This article is the first step in a brief tour of the Angular framework for experienced web developers- specially those coming from another framework like React, Vue, or Ember.

With a decent grasp of HTML, CSS, TypeScript, HTTP and NodeJS, you should be able to easily follow along, and at the end of the series, have a good idea of how Angular works and how to go about using it to build modern web applications.

> This article was last updated on 22nd August 2020.

<a name="toc"></a>

## Table of Contents

- [Preamble](#preamble)
- [Web apps](#web_apps)
- [Web frameworks](#web_frameworks)
- [Angular vs React](#angular_vs_react)
- [A history lesson](#angular_evolution)
- [Getting started with Angular](#angular_first_steps)
- [The layout of an Angular workspace](#angular_workspace_files)
- [An Angular project](#angular_project_files)
- [What next?](#angular_learning_resources_and_community)

<a name="preamble"></a>

## Preamble

Two years after the initial announcement at [NgConf 2014 Europe](https://www.youtube.com/watch?v=gNmWybAyBHI), in the September of 2016, Angular version 2 was finally released. It was a massive overhaul of the framework that greatly improved the internal architecture and overall developer experience. Unfortunately, all those benefits came at a cost.

Version 2 was not at all backwards compatible with version 1, and at the time, there was no clear upgrade path. Version 2 was, for all practical purposes, a new framework! This caused some developers to jump ship to other frameworks such as React, Vue and Ember, or hold out from upgrading altogether.

Now contrast this to what happened on the February of 2020 when [version 9](https://blog.angular.io/version-9-of-angular-now-available-project-ivy-has-arrived-23c97b63cfa3) of Angular was released. Similar to how Angular moved from using the *template engine* to *view engine* with version 2, the rendering engine was replaced again, with version 9 moving to *Ivy* as the default. But this time, the developer experience was quite different. There were no angry tweets or posts about how difficult it is to upgrade- in fact, it was an uneventful, unremarkable, and downright boring upgrade experience.

So let me start this brief tour by saying that, Angular, with its already comprehensive feature set, great community, and now with a *very boring upgrade story* is a framework that gives very little reason for developers to stay away from!

Back to [TOC](#toc).

<a name="web_apps"></a>

## Web apps

Let's take a step back and look at the big picture behind what we do as web developers.

A web app, by definition, lives at a particular URL and is loaded by and executed inside a web browser.

When the browser accesses this URL, it obtains the initial HTML code for the web app. This HTML code links to the CSS, JavaScript, and other asset files it needs.

The browser loads these files as well and renders the user interface of the web app on to the users' screen. During this process, an in-memory representation of the web page, a.k.a. web document is constructed by the browser and is maintained throughout the execution lifetime of the web app.

This in-memory representation of the web document is exposed to the web app's JavaScript code for manipulation via the DOM API. The Document Object Model is organized as a tree of nodes and logically sits between our applications' JS code and the view the user sees.

![Web page, DOM, and web app code](https://dev-to-uploads.s3.amazonaws.com/i/q7341clmce1naax0ifky.png)

Each tag in the HTML file results in a corresponding node in the DOM tree. Each of these nodes correspond to a particular slice of the rendered view. When the user interacts with the view, the browser fires events, which the DOM API allows our JS code to listen to.

So, a web app is programmed by:

- HTML code to define the ***initial structure*** of its user interface
- CSS code to define the ***initial styling*** of its user interface
- JavaScript code that:
  - Uses the DOM API to manipulate the structure and styling of the user interface
  - Uses other Web APIs for things such as accessing the network and saving data locally
  - Implements the actual business logic and deliver value to the user

Although manipulating the DOM using the DOM API directly is very powerful, it is more convenient to use abstractions on top of that. This is where libraries like jQuery & React, and frameworks like Angular, Vue, and Ember comes in.

Back to [TOC](#toc).

<a name="web_frameworks"></a>

## Web frameworks

The first library to enjoy widespread adoption was [jQuery](https://jquery.com), which  appeared around 2006 and addressed the problem of incompatibilities in how the Web APIs were implemented across the major web browsers.   It also gave a simple, elegant API on top of the original DOM API for accessing and manipulating the DOM. 

The next challenge was to have an easier way for our web apps'  data and logic, typically organized as JS classes and or functions, to drive the user interface behind the DOM API. This question was addressed by multiple efforts that started to appear around 2010- such as, [Knockout.js](https://knockoutjs.com), [Backbone.js](https://backbonejs.org), [SproutCore](https://sproutcore.com), and [AngularJS](https://angularjs.org).  These were followed by [EmberJS](https://emberjs.com) which sprang out from SproutCore in 2011 December.

[React](https://reactjs.org/)  launched in 2013 with its virtual DOM and component based approach to UI composition that challenged the mostly MVC based approaches of its predecessors.  And [Vue.js](https://vuejs.org/) appeared in 2014 combining features of both AngularJS and React.

In 2016 [Angular](https://angular.io) was released, a complete reboot of Angular, which ditched the MVC based approach of AngularJS in favor of a component based approach.

Back to [TOC](#toc).

<a name="angular_vs_react"></a>

## Angular vs React

Angular is often compared with React. 

The first thing to note is that React is a _library_ for building user interfaces whereas Angular is a _framework_ for building applications. Given that applications certainly need user interfaces, it follows that Angular covers  a much bigger scope than React. This unfortunately also means that Angular has a much bigger learning curve than React so developers are quicker to get productive in React than in Angular. So for simple apps, React seems to be a better choice.

But the proper comparison is to compare Angular with *React core + React ecosystem*. With React, most of the pieces that Angular provides as part of the framework needs to be picked and chosen from a large buffet of community offerings. This is a good and a bad thing. It is good because it gives more options to the developer so she can put together a highly customized solution. And it is bad for exactly the same reason. Too much choice is often problematic, specially for those beginners who looked at Angular, thought it had too much of a learning curve, gave up and instead picked React. They breeze through the core React concepts in a few weeks and then realize that building their apps requires quite a few more tools than what the React library provides.

So for complex apps, specially CRUD style enterprisy ones, arguably, Angular has a ***smaller total learning curve*** and a better return on intellectual investment than React.

Angular is a well architectured comprehensive application framework. So as you build bigger applications and maintain them for longer, you realize that the upfront learning cost of Angular is offset by the developer productivity that Angular continues to give over the full lifecycle of the web application.

> Once developers get through the core concepts that underlies the Angular framework, they realize that the going gets much more easier and that they have in their possession a much more powerful toolbox with a set of cohesive tools to wield at many application development challenges.

That was how Angular compares to React at a framework level. There is also a fundamental difference in the way the UI library parts of the two frameworks handle DOM manipulation.

Though both Angular and React puts components front and center, as the building block for composing user interfaces out of, React uses what is known as a virtual DOM for manipulating the DOM whereas Angular works with the real DOM.

The virtual DOM is basically an in-memory representation of the real DOM so that when detecting changes, React does not have to touch the real DOM. That makes change detection faster.

Angular has adopted a totally different approach where the Angular compiler augments our app code with framework code. Then this hybrid code operates directly on the real DOM. The extra code is responsible for binding data between our "apps' objects" and "DOM objects" as well as handling DOM events from inside our apps' methods. The compiler tree-shakes unused framework and application code so as to produce leaner code bundles.

Both approaches have pros and cons- and each framework inspires the other to innovate. So assertions about each framework that was true few years ago may not hold today. As developers, our responsibility is to understand the task at hand and the pick the right tool for that particular job.

Back to [TOC](#toc).

<a name="angular_evolution"></a>

## A history lesson

On 2020 October, Angular will be 10 years old. Over the last decade, Angular has helped transform the way we architecture and build web applications and in turn had transformed itself in lockstep with the evolution of the web platform. Let's take a look back at how Angular evolved over the years.

AngularJS was [announced by Miško Hevery](http://misko.hevery.com/2009/09/28/hello-world-angular-is-here/) in 2009 and version 1 was released in 2010. 

![Angular announcement by Miško Hevery](https://dev-to-uploads.s3.amazonaws.com/i/pk89jwl7321ia1jaxzfx.png)

It came into a world looking for a better way to build web applications- and it really took off.

When v2 was released in 2016 September. It was a complete rewrite and was branded Angular instead of AngularJS. Most people felt that it was a completely different framework that happened to be done by the same team under almost the same name. In some senses it was, for example the ***template engine*** at the  core of Angular was replaced by the ***view engine*** and the MVC architecture was replaced with a component based one.

There was no v3 of Angular because the Angular Router for Angular v2 had already been released as v3. Angular v4 was released 2017 March and  v5 in  2017 November.

Angular v6 was released 2018 May. It focused on synchronization of the Angular toolchain- core, compiler, CLI, material, CDK, and a commitment was given to the community to keep things in sync going forward. A way to help users update their applications to newer versions of Angular was introduced in the form of a new CLI command called `update`. Another new CLI command `add` was introduced to help generate common application parts such as components.

Angular v7, released in 2018 October, introduced ***schematics***, a mechanism for customizing the files CLI generates with the `add` command.


In 2019 May,  Angular v8 introduced ***differential loading***, which allowed the generation of smaller apps (often 7 to 20 percent smaller) by creating two separate bundles- one for evergreen browsers and one for legacy browsers. Version 8 also introduced ***builders***, which allowed the customization of the tools used and the order in which they are run by the compiler.

Angular v8 was released in 2020 March. The new rendering engine, ***Ivy***, that replaces the template engine used since v2 was available as an opt-in. Ivy was subsequently made the default for Angular at version 9, which was released in 2020 February.

Version 10, that came out on 2020 June, is the latest major release. It introduced few more features aimed at producing leaner and more maintainable Angular apps. For example, the CLI now warns when a dependency is packaged with CommonJS.  A `strict` option for the  `ng new` CLI command was added which enables strict mode in TypeScript and strict type checking in templates. The apps are now configured as side effect free, which makes them more tree shakable thus leading to smaller bundles.

Back to [TOC](#toc).

<a name="angular_first_steps"></a>

## Getting started with Angular

With a current release of NodeJS already installed in your system, install the `@angular/cli` package globally:

```shell
npm install -g @angular/cli
```

Now you should be able to access the Angular CLI with `ng` command: Try running `ng version` and `ng help`.

Open a shell and change directory to wherever you save your coding projects and use the `ng new` command to generate a new Angular workspace:

```shell
ng new into-angular \
        --strict --create-application="false"
```

An `into-angular` directory gets created with the workspace files and a Git repository gets initialized.

The [strict](https://angular.io/guide/strict-mode) option, introduced in Angular 10, enforces a set of best practices such as stronger type checking and making parts of the application self-contained and side effect free.

Let's add a web application project to our workspace:

```shell
ng generate application hello \
       --strict  --inline-template  --inline-style
```

Change into the generated workspace directory and use the `ng serve` command to build the `hello` project and run in the development server with live reload enabled. 

```shell
cd into-angular
ng serve hello --open
```

The `--open` option opens the default web browser at the URL exposed by the development server. 

We can run the unit tests with:

```shell
ng test hello
```

And the end-to-end tests with:

```shell
ng e2e hello
```

We can do a production build with:

```shell
ng build hello --prod
```

The production build is generated in the `into-angular/dist/hello` folder, and the output sizes are quite small- no unreasonable overhead from the framework!

```
 535B   index.html
   0B   styles.3ff695c00d717f2d2a11.css
 1.5K   runtime.e227d1a0e31cbccbf8ec.js
  36K   polyfills.9e86b32c42185429d576.js
 102K   main.77129eaa6e421d8e7131.js
  13K   3rdpartylicenses.txt
 948B   favicon.ico
```

To serve the production build locally, install the `serve` utility and "serve" this directory:

```shell
npm install -g serve

serve into-angular/dist/hello
```

Back to [TOC](#toc).

<a name="angular_workspace_files"></a>

## The layout of an Angular workspace

The generated Angular workspace directory contains configuration files that applies to all projects.

![Directory layout of an Angular workspace](https://dev-to-uploads.s3.amazonaws.com/i/qsc2trry3p53fhugamht.png)

All projects in a workspace share NPM dependencies. So even if you have ten projects inside the `projects` directory, you would have only one `node_modules` directory- the one at the workspace level.

The `tsconfig.base.json` declares the base options for the TypeScript compiler. These get extended by project level tsconfig files. 

The workspace level `tsconfig.json` file is for code editors to pickup . So is the `.editorconfig` file, which declares coding style options like indenting, quotes, brackets, tabs/spaces.

The `angular.json` file is where we configure the behavior of the Angular compiler.

```json
"defaultProject": "hello",
"newProjectRoot": "projects",
"projects": {
  "hello": {
    "projectType": "application",
    "root": "projects/hello",
    "sourceRoot": "projects/hello/src",
    "prefix": "app",
    "schematics": {},
    "architect": {
      "build": {
        "builder": "@angular-devkit/build-angular:browser",
        "options": {},
        "configurations": {
          "production": {}
        }
      },
      "serve": {},
      "test": {},
      "e2e": {},
```

Since the `defaultProject` is set to *hello*, in `ng` commands, we can drop the project name and still have the command act on the default `hello` project. So, we can just do a `ng serve` and get the *hello* project served.

In our `hello` project, we have the `projectType` set to application. The other option here is *library*. Later in our tour, we will see how to create a library project and reuse it in multiple application projects. 

Soon we will be generating components and other directives- these have a *selector* that is used inside HTML templates to activate the directive. The string we specify in the `prefix` option is used as a prefix for the selector when we generate the directive with `ng generate directive` or `ng generate component`.

**Schematics** are the blueprints for the artifacts that the Angular CLI generates with `ng generate` command- applications, libraries, components, generic directives, services, pipes, and so on. Options for these go under the `schematics` section. The `architect` section is for configuring the Angular CLI build pipeline. Angular let's us customize both of these aspects- what the various generators output (with custom schematics) and what the build pipeline does (with custom builders). Later in this tour, we will see how!

Back to [TOC](#toc).

<a name="angular_project_files"></a>

## An Angular project

The generated web application project, *hello*, looks like this:

![Directory layout of an Angular project](https://dev-to-uploads.s3.amazonaws.com/i/eifxvjijtb3q8aa0bro6.png)

The `.browserslistrc` file declares browsers supported by this project. Angular uses this information to adjust the CSS/JS output of the compiler.

Angular uses [Jasmine](https://jasmine.github.io/) for writing unit tests and [Karma](https://karma-runner.github.io/),  configured with the`karma.conf.js` file,  for running them.

There are two tsconfig files- one for the application code, and one for the unit test code. These are for configuring the TypeScript compiler. The `tslint.json` file configures the TypeScript linter, TSLint. All three files extend their parents from the workspace directory.

The `src` folder contains all the source code for the application including unit tests. The `e2e` folder contains all the end to end tests. Let's dive into what they contain.

![Layout of the e2e directory of an Angular web application project](https://dev-to-uploads.s3.amazonaws.com/i/uirrx2na8z7oqzvb3smh.png)

[Protractor](https://www.protractortest.org), configured with  `protractor.config.js`, is used for writing end to end tests. The `app.po.ts` file is a "Page Object" for the our app's landing page.  This has convenience methods for use in the actual end to end test file, in this case, `app.e2e-spec.ts`.

![Layout of the src directory of an Angular web application project](https://dev-to-uploads.s3.amazonaws.com/i/tyk3m0tisaycx09alw9t.png)

The `index.html` file is the main template. This is where the root component of our app's component hierarchy gets referenced. Entry point for application code is the `main.ts` file. For running unit tests, the entry point is the `test.ts` file.

Styles shared across the app are in the `styles.css` file. Later we will see that components can define their own private styles.

The `app` directory is named after the name of the *code module* it holds- in this case, *app*. The `AppModule` class is found in `app.module.ts`.  This is the default module for holding our applications’ parts- components, other directives, services, pipes and so on. As we build bigger applications we will need more modules so that we can divide up the app into more manageable sections and load each section lazily when needed.

The `app.component.ts` declares the `AppComponent` and  `app.component.spec.ts` contains unit tests for it. `AppComponent` sits at the root of our apps' component hierarchy. This is the component that get referenced in `index.html` causing our whole app to recursively get loaded.

Back to [TOC](#toc).

<a name="angular_learning_resources_and_community"></a>

## What next?

In the next article we will take a closer look at the primary building block of an angular application, the ***component***. Then we will see how to create ***services*** that interact with the world outside our component and how to ***inject*** them where they are needed. On subsequent articles, we will continue our tour by looking at routing, forms, material styling, animation, internationalization, accessibility, testing, and keeping the application up-to date as Angular itself improves.

Back to [TOC](#toc).