In this hello world style tutorial, we will follow a step by step guide to a working Angular 4 application. We will also be able to demonstrate the two way binding feature, which will make sure that the browser reflects any changes to the model or the HTML code.

Note: while the latest quickstart example is using Angular 4 code, the tutorial works also for Angular 2.

What is Angular?

Angular (a.k.a. AngularJS) is a framework for dynamic web apps that is ideal for creating one page applications. A typical index.html file contains a custom HTML tag that is defined in an Angular component. The Angular component maps to a HTML template, which can contain variables in double curly brackets {{variable}}. The variables are defined within Angular components. Below, we will see a simple example and review the HTML index file and the template + model defined in a Angular component.

Angular Hello World via Quickstart

In this chapter, we will learn how to create an Angular Hello World application within a Docker CentoOS container. We will follow the fourth path shown on this article on courcetro. This is the only way I have found that will work on Katacoda (because of its low RAM consumption). The hands-on playground on Katacoda allows you to perform all steps in a console in your browser without the need to install any Docker host on your machine:

Click here to start your Katacoda course (requires free sign-up).

For the case you prefer to run a local test within a Docker container, follow the steps below.

Step 1: Start CentOS Container

We had problems with NPM on the latest Ubuntu, so we prefer to use a CentOS 7 container:

(dockerhost)$ docker run -it -p 3000:3000 centos:7 bash

Step 2: Install Git and NPM

Within the container, we need to install Git and NPM. One way of doing so is to install Git and NPM from the EPEL release (see here for other ways to install NPM):

(container)# yum install -y epel-release; yum install -y git npm

If you want to skip the lengthy installation process, you also can run a docker container from a Docker image, where npm and git is already installed:

docker run -it -p 3000:3000 oveits/centos_npm_git bash
(container)# npm -v
3.10.10

Step 3: Clone Quickstart Template

Now we clone the Quickstart Template for angular:

(container)# git clone https://github.com/angular/quickstart

Step 4: Install Dependencies

Now we install packages via NPM:

(container)# cd quickstart; npm i

Step 5: Start Service

Now we can start the service in the background like follows:

(container)# npm start &
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
npm WARN deprecated minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
angular-quickstart@1.0.0 /quickstart
+-- @angular/common@4.0.3
+-- @angular/compiler@4.0.3
+-- @angular/core@4.0.3
+-- @angular/forms@4.0.3
+-- @angular/http@4.0.3
+-- @angular/platform-browser@4.0.3
+-- @angular/platform-browser-dynamic@4.0.3
+-- @angular/router@4.0.3
+-- @types/jasmine@2.5.36
+-- @types/node@6.0.78
+-- angular-in-memory-web-api@0.3.2
+-- canonical-path@0.0.2
+-- concurrently@3.4.0
| +-- chalk@0.5.1
| | +-- ansi-styles@1.1.0
| | +-- escape-string-regexp@1.0.5
| | +-- has-ansi@0.1.0
| | | `-- ansi-regex@0.2.1
| | +-- strip-ansi@0.3.0
| | `-- supports-color@0.2.0
| +-- commander@2.6.0
| +-- date-fns@1.28.5
| +-- rx@2.3.24
| +-- spawn-command@0.0.2-1
| +-- supports-color@3.2.3
| | `-- has-flag@1.0.0
| `-- tree-kill@1.1.0
+-- core-js@2.4.1
+-- jasmine-core@2.4.1
+-- karma@1.7.0
| +-- bluebird@3.5.0
| +-- body-parser@1.17.2
| | +-- bytes@2.4.0
| | +-- content-type@1.0.2
| | +-- debug@2.6.7
| | | `-- ms@2.0.0
| | +-- depd@1.1.0
| | +-- http-errors@1.6.1
| | | +-- setprototypeof@1.0.3
| | | `-- statuses@1.3.1
| | +-- iconv-lite@0.4.15
| | +-- on-finished@2.3.0
| | | `-- ee-first@1.1.1
| | +-- qs@6.4.0
| | +-- raw-body@2.2.0
| | | `-- unpipe@1.0.0
| | `-- type-is@1.6.15
| |   +-- media-typer@0.3.0
| |   `-- mime-types@2.1.15
| |     `-- mime-db@1.27.0
| +-- chokidar@1.7.0
| | +-- anymatch@1.3.0
| | | `-- arrify@1.0.1
| | +-- async-each@1.0.1
| | +-- glob-parent@2.0.0
| | +-- inherits@2.0.3
| | +-- is-binary-path@1.0.1
| | | `-- binary-extensions@1.8.0
| | +-- is-glob@2.0.1
| | | `-- is-extglob@1.0.0
| | +-- path-is-absolute@1.0.1
| | `-- readdirp@2.1.0
| |   +-- readable-stream@2.2.11
| |   | +-- isarray@1.0.0
| |   | +-- process-nextick-args@1.0.7
| |   | +-- safe-buffer@5.0.1
| |   | `-- string_decoder@1.0.2
| |   |   `-- safe-buffer@5.0.1
| |   `-- set-immediate-shim@1.0.1
| +-- colors@1.1.2
| +-- combine-lists@1.0.1
| +-- connect@3.6.2
| | +-- finalhandler@1.0.3
| | | +-- encodeurl@1.0.1
| | | `-- escape-html@1.0.3
| | +-- parseurl@1.3.1
| | `-- utils-merge@1.0.0
| +-- di@0.0.1
| +-- dom-serialize@2.2.1
| | +-- custom-event@1.0.1
| | +-- ent@2.2.0
| | +-- extend@3.0.1
| | `-- void-elements@2.0.1
| +-- expand-braces@0.1.2
| | +-- array-slice@0.2.3
| | +-- array-unique@0.2.1
| | `-- braces@0.1.5
| |   `-- expand-range@0.1.1
| |     +-- is-number@0.1.1
| |     `-- repeat-string@0.2.2
| +-- glob@7.1.2
| | +-- fs.realpath@1.0.0
| | +-- inflight@1.0.6
| | | `-- wrappy@1.0.2
| | `-- once@1.4.0
| +-- graceful-fs@4.1.11
| +-- http-proxy@1.16.2
| | +-- eventemitter3@1.2.0
| | `-- requires-port@1.0.0
| +-- isbinaryfile@3.0.2
| +-- lodash@3.10.1
| +-- log4js@0.6.38
| | +-- readable-stream@1.0.34
| | | +-- core-util-is@1.0.2
| | | +-- isarray@0.0.1
| | | `-- string_decoder@0.10.31
| | `-- semver@4.3.6
| +-- mime@1.3.6
| +-- minimatch@3.0.4
| | `-- brace-expansion@1.1.8
| |   +-- balanced-match@1.0.0
| |   `-- concat-map@0.0.1
| +-- optimist@0.6.1
| | +-- minimist@0.0.10
| | `-- wordwrap@0.0.3
| +-- qjobs@1.1.5
| +-- range-parser@1.2.0
| +-- safe-buffer@5.1.0
| +-- socket.io@1.7.3
| | +-- debug@2.3.3
| | | `-- ms@0.7.2
| | +-- engine.io@1.8.3
| | | +-- accepts@1.3.3
| | | | `-- negotiator@0.6.1
| | | +-- base64id@1.0.0
| | | +-- cookie@0.3.1
| | | +-- debug@2.3.3
| | | | `-- ms@0.7.2
| | | `-- engine.io-parser@1.3.2
| | |   +-- after@0.8.2
| | |   +-- arraybuffer.slice@0.0.6
| | |   +-- base64-arraybuffer@0.1.5
| | |   +-- blob@0.0.4
| | |   `-- wtf-8@1.0.0
| | +-- has-binary@0.1.7
| | | `-- isarray@0.0.1
| | +-- object-assign@4.1.0
| | +-- socket.io-adapter@0.5.0
| | | `-- debug@2.3.3
| | |   `-- ms@0.7.2
| | +-- socket.io-client@1.7.3
| | | +-- backo2@1.0.2
| | | +-- component-bind@1.0.0
| | | +-- component-emitter@1.2.1
| | | +-- debug@2.3.3
| | | | `-- ms@0.7.2
| | | +-- engine.io-client@1.8.3
| | | | +-- component-emitter@1.2.1
| | | | +-- component-inherit@0.0.3
| | | | +-- debug@2.3.3
| | | | | `-- ms@0.7.2
| | | | +-- has-cors@1.1.0
| | | | +-- parsejson@0.0.3
| | | | +-- parseqs@0.0.5
| | | | +-- xmlhttprequest-ssl@1.5.3
| | | | `-- yeast@0.1.2
| | | +-- indexof@0.0.1
| | | +-- object-component@0.0.3
| | | +-- parseuri@0.0.5
| | | | `-- better-assert@1.0.2
| | | |   `-- callsite@1.0.0
| | | `-- to-array@0.1.4
| | `-- socket.io-parser@2.3.1
| |   +-- component-emitter@1.1.2
| |   +-- debug@2.2.0
| |   | `-- ms@0.7.1
| |   +-- isarray@0.0.1
| |   `-- json3@3.3.2
| +-- source-map@0.5.6
| +-- tmp@0.0.31
| | `-- os-tmpdir@1.0.2
| `-- useragent@2.1.13
|   `-- lru-cache@2.2.4
+-- karma-chrome-launcher@2.1.1
| +-- fs-access@1.0.1
| | `-- null-check@1.0.0
| `-- which@1.2.14
|   `-- isexe@2.0.0
+-- karma-cli@1.0.1
| `-- resolve@1.3.3
|   `-- path-parse@1.0.5
+-- karma-jasmine@1.1.0
+-- karma-jasmine-html-reporter@0.2.2
+-- lite-server@2.3.0
| +-- browser-sync@2.18.12
| | +-- browser-sync-client@2.5.1
| | | +-- etag@1.8.0
| | | `-- fresh@0.3.0
| | +-- browser-sync-ui@0.6.3
| | | +-- async-each-series@0.1.1
| | | +-- stream-throttle@0.1.3
| | | | `-- limiter@1.1.0
| | | `-- weinre@2.0.0-pre-I0Z7U9OV
| | |   +-- express@2.5.11
| | |   | +-- connect@1.9.2
| | |   | | `-- formidable@1.0.17
| | |   | +-- mime@1.2.4
| | |   | +-- mkdirp@0.3.0
| | |   | `-- qs@0.4.2
| | |   +-- nopt@3.0.6
| | |   | `-- abbrev@1.1.0
| | |   `-- underscore@1.7.0
| | +-- bs-recipes@1.3.4
| | +-- connect@3.5.0
| | | +-- debug@2.2.0
| | | | `-- ms@0.7.1
| | | `-- finalhandler@0.5.0
| | +-- dev-ip@1.0.1
| | +-- easy-extender@2.3.2
| | | `-- lodash@3.10.1
| | +-- eazy-logger@3.0.2
| | | `-- tfunk@3.1.0
| | |   +-- chalk@1.1.3
| | |   | +-- ansi-styles@2.2.1
| | |   | +-- has-ansi@2.0.0
| | |   | | `-- ansi-regex@2.1.1
| | |   | +-- strip-ansi@3.0.1
| | |   | `-- supports-color@2.0.0
| | |   `-- object-path@0.9.2
| | +-- emitter-steward@1.0.0
| | +-- fs-extra@3.0.1
| | | +-- jsonfile@3.0.0
| | | `-- universalify@0.1.0
| | +-- http-proxy@1.15.2
| | +-- immutable@3.8.1
| | +-- localtunnel@1.8.2
| | | +-- debug@2.2.0
| | | | `-- ms@0.7.1
| | | +-- openurl@1.1.0
| | | `-- yargs@3.29.0
| | |   +-- camelcase@1.2.1
| | |   `-- window-size@0.1.4
| | +-- micromatch@2.3.11
| | | +-- arr-diff@2.0.0
| | | | `-- arr-flatten@1.0.3
| | | +-- braces@1.8.5
| | | | +-- expand-range@1.8.2
| | | | | `-- fill-range@2.2.3
| | | | |   +-- is-number@2.1.0
| | | | |   +-- isobject@2.1.0
| | | | |   +-- randomatic@1.1.7
| | | | |   | +-- is-number@3.0.0
| | | | |   | | `-- kind-of@3.2.2
| | | | |   | `-- kind-of@4.0.0
| | | | |   `-- repeat-string@1.6.1
| | | | +-- preserve@0.2.0
| | | | `-- repeat-element@1.1.2
| | | +-- expand-brackets@0.1.5
| | | | `-- is-posix-bracket@0.1.1
| | | +-- extglob@0.3.2
| | | +-- filename-regex@2.0.1
| | | +-- kind-of@3.2.2
| | | | `-- is-buffer@1.1.5
| | | +-- normalize-path@2.1.1
| | | | `-- remove-trailing-separator@1.0.2
| | | +-- object.omit@2.0.1
| | | | +-- for-own@0.1.5
| | | | | `-- for-in@1.0.2
| | | | `-- is-extendable@0.1.1
| | | +-- parse-glob@3.0.4
| | | | +-- glob-base@0.3.0
| | | | `-- is-dotfile@1.0.3
| | | `-- regex-cache@0.4.3
| | |   +-- is-equal-shallow@0.1.3
| | |   `-- is-primitive@2.0.0
| | +-- opn@4.0.2
| | | `-- pinkie-promise@2.0.1
| | |   `-- pinkie@2.0.4
| | +-- portscanner@2.1.1
| | | +-- async@1.5.2
| | | `-- is-number-like@1.0.7
| | |   +-- bubleify@0.5.1
| | |   | `-- buble@0.12.5
| | |   |   +-- acorn@3.3.0
| | |   |   +-- acorn-jsx@3.0.1
| | |   |   +-- acorn-object-spread@1.0.0
| | |   |   +-- chalk@1.1.3
| | |   |   | +-- ansi-styles@2.2.1
| | |   |   | +-- has-ansi@2.0.0
| | |   |   | | `-- ansi-regex@2.1.1
| | |   |   | +-- strip-ansi@3.0.1
| | |   |   | `-- supports-color@2.0.0
| | |   |   +-- magic-string@0.14.0
| | |   |   | `-- vlq@0.2.2
| | |   |   +-- minimist@1.2.0
| | |   |   `-- os-homedir@1.0.2
| | |   `-- lodash.isfinite@3.3.2
| | +-- qs@6.2.1
| | +-- resp-modifier@6.0.2
| | +-- rx@4.1.0
| | +-- serve-index@1.8.0
| | | +-- batch@0.5.3
| | | +-- debug@2.2.0
| | | | `-- ms@0.7.1
| | | `-- http-errors@1.5.1
| | |   `-- setprototypeof@1.0.2
| | +-- serve-static@1.12.2
| | | `-- send@0.15.2
| | |   +-- debug@2.6.4
| | |   | `-- ms@0.7.3
| | |   +-- destroy@1.0.4
| | |   +-- fresh@0.5.0
| | |   +-- mime@1.3.4
| | |   `-- ms@1.0.0
| | +-- server-destroy@1.0.1
| | +-- socket.io@1.6.0
| | | +-- debug@2.3.3
| | | | `-- ms@0.7.2
| | | `-- engine.io@1.8.0
| | |   +-- base64id@0.1.0
| | |   +-- debug@2.3.3
| | |   | `-- ms@0.7.2
| | |   +-- engine.io-parser@1.3.1
| | |   | +-- after@0.8.1
| | |   | `-- has-binary@0.1.6
| | |   |   `-- isarray@0.0.1
| | |   `-- ws@1.1.1
| | +-- socket.io-client@1.6.0
| | | +-- component-emitter@1.2.1
| | | +-- debug@2.3.3
| | | | `-- ms@0.7.2
| | | `-- engine.io-client@1.8.0
| | |   `-- debug@2.3.3
| | |     `-- ms@0.7.2
| | +-- ua-parser-js@0.7.12
| | `-- yargs@6.4.0
| |   +-- camelcase@3.0.0
| |   +-- cliui@3.2.0
| |   | +-- strip-ansi@3.0.1
| |   | | `-- ansi-regex@2.1.1
| |   | `-- wrap-ansi@2.1.0
| |   |   `-- strip-ansi@3.0.1
| |   |     `-- ansi-regex@2.1.1
| |   +-- decamelize@1.2.0
| |   +-- get-caller-file@1.0.2
| |   +-- os-locale@1.4.0
| |   | `-- lcid@1.0.0
| |   |   `-- invert-kv@1.0.0
| |   +-- read-pkg-up@1.0.1
| |   | +-- find-up@1.1.2
| |   | | `-- path-exists@2.1.0
| |   | `-- read-pkg@1.1.0
| |   |   +-- load-json-file@1.1.0
| |   |   | +-- parse-json@2.2.0
| |   |   | | `-- error-ex@1.3.1
| |   |   | |   `-- is-arrayish@0.2.1
| |   |   | `-- strip-bom@2.0.0
| |   |   |   `-- is-utf8@0.2.1
| |   |   +-- normalize-package-data@2.3.8
| |   |   | +-- hosted-git-info@2.4.2
| |   |   | +-- is-builtin-module@1.0.0
| |   |   | | `-- builtin-modules@1.1.1
| |   |   | `-- validate-npm-package-license@3.0.1
| |   |   |   +-- spdx-correct@1.0.2
| |   |   |   | `-- spdx-license-ids@1.2.2
| |   |   |   `-- spdx-expression-parse@1.0.4
| |   |   `-- path-type@1.1.0
| |   +-- require-directory@2.1.1
| |   +-- require-main-filename@1.0.1
| |   +-- set-blocking@2.0.0
| |   +-- string-width@1.0.2
| |   | +-- code-point-at@1.1.0
| |   | +-- is-fullwidth-code-point@1.0.0
| |   | | `-- number-is-nan@1.0.1
| |   | `-- strip-ansi@3.0.1
| |   |   `-- ansi-regex@2.1.1
| |   +-- which-module@1.0.0
| |   +-- window-size@0.2.0
| |   +-- y18n@3.2.1
| |   `-- yargs-parser@4.2.1
| |     `-- camelcase@3.0.0
| +-- connect-history-api-fallback@1.3.0
| +-- connect-logger@0.0.1
| | `-- moment@2.18.1
| `-- minimist@1.2.0
+-- lodash@4.17.4
+-- protractor@4.0.14
| +-- @types/q@0.0.32
| +-- @types/selenium-webdriver@2.53.37
| +-- adm-zip@0.4.7
| +-- chalk@1.1.3
| | +-- ansi-styles@2.2.1
| | +-- has-ansi@2.0.0
| | | `-- ansi-regex@2.1.1
| | +-- strip-ansi@3.0.1
| | `-- supports-color@2.0.0
| +-- jasmine@2.4.1
| | +-- exit@0.1.2
| | `-- glob@3.2.11
| |   `-- minimatch@0.3.0
| |     `-- sigmund@1.0.1
| +-- jasminewd2@0.0.10
| +-- q@1.4.1
| +-- saucelabs@1.3.0
| | `-- https-proxy-agent@1.0.0
| |   `-- agent-base@2.1.1
| |     `-- semver@5.0.3
| +-- selenium-webdriver@2.53.3
| | +-- adm-zip@0.4.4
| | +-- tmp@0.0.24
| | +-- ws@1.1.2
| | | +-- options@0.0.6
| | | `-- ultron@1.0.2
| | `-- xml2js@0.4.4
| |   +-- sax@0.6.1
| |   `-- xmlbuilder@9.0.0
| +-- source-map-support@0.4.15
| `-- webdriver-manager@10.3.0
|   +-- del@2.2.2
|   | +-- globby@5.0.0
|   | | `-- array-union@1.0.2
|   | |   `-- array-uniq@1.0.3
|   | +-- is-path-cwd@1.0.0
|   | +-- is-path-in-cwd@1.0.0
|   | | `-- is-path-inside@1.0.0
|   | |   `-- path-is-inside@1.0.2
|   | `-- pify@2.3.0
|   +-- ini@1.3.4
|   +-- minimist@1.2.0
|   +-- request@2.78.0
|   | +-- aws-sign2@0.6.0
|   | +-- aws4@1.6.0
|   | +-- caseless@0.11.0
|   | +-- combined-stream@1.0.5
|   | | `-- delayed-stream@1.0.0
|   | +-- forever-agent@0.6.1
|   | +-- form-data@2.1.4
|   | | `-- asynckit@0.4.0
|   | +-- har-validator@2.0.6
|   | | +-- chalk@1.1.3
|   | | | +-- ansi-styles@2.2.1
|   | | | +-- has-ansi@2.0.0
|   | | | | `-- ansi-regex@2.1.1
|   | | | +-- strip-ansi@3.0.1
|   | | | `-- supports-color@2.0.0
|   | | +-- commander@2.9.0
|   | | | `-- graceful-readlink@1.0.1
|   | | `-- is-my-json-valid@2.16.0
|   | |   +-- generate-function@2.0.0
|   | |   +-- generate-object-property@1.2.0
|   | |   | `-- is-property@1.0.2
|   | |   +-- jsonpointer@4.0.1
|   | |   `-- xtend@4.0.1
|   | +-- hawk@3.1.3
|   | | +-- boom@2.10.1
|   | | +-- cryptiles@2.0.5
|   | | +-- hoek@2.16.3
|   | | `-- sntp@1.0.9
|   | +-- http-signature@1.1.1
|   | | +-- assert-plus@0.2.0
|   | | +-- jsprim@1.4.0
|   | | | +-- assert-plus@1.0.0
|   | | | +-- extsprintf@1.0.2
|   | | | +-- json-schema@0.2.3
|   | | | `-- verror@1.3.6
|   | | `-- sshpk@1.13.1
|   | |   +-- asn1@0.2.3
|   | |   +-- assert-plus@1.0.0
|   | |   +-- bcrypt-pbkdf@1.0.1
|   | |   +-- dashdash@1.14.1
|   | |   | `-- assert-plus@1.0.0
|   | |   +-- ecc-jsbn@0.1.1
|   | |   +-- getpass@0.1.7
|   | |   | `-- assert-plus@1.0.0
|   | |   +-- jsbn@0.1.1
|   | |   `-- tweetnacl@0.14.5
|   | +-- is-typedarray@1.0.0
|   | +-- isstream@0.1.2
|   | +-- json-stringify-safe@5.0.1
|   | +-- node-uuid@1.4.8
|   | +-- oauth-sign@0.8.2
|   | +-- qs@6.3.2
|   | +-- stringstream@0.0.5
|   | +-- tough-cookie@2.3.2
|   | | `-- punycode@1.4.1
|   | `-- tunnel-agent@0.4.3
|   `-- semver@5.3.0
+-- rimraf@2.6.1
+-- rxjs@5.0.1
| `-- symbol-observable@1.0.4
+-- systemjs@0.19.40
| `-- when@3.7.8
+-- tslint@3.15.1
| +-- diff@2.2.3
| +-- findup-sync@0.3.0
| | `-- glob@5.0.15
| `-- underscore.string@3.3.4
|   +-- sprintf-js@1.1.1
|   `-- util-deprecate@1.0.2
+-- typescript@2.1.6
`-- zone.js@0.8.12

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

The warnings can be ignored for the purpose of this tutorial.

Step 6: Load Application

You can load the angular application on the browser on http://localhost:3000

Note: if your Docker host is running on VirtualBox, you might need to map the port 3000 from your local machine to the VirtualBox VM:

Step 7 (optional): Review Angular Files

src/index.html

The index.html is the file that is loaded by the browser.

<!DOCTYPE html>
<html>
  <head>
    <title>Angular QuickStart</title>
    <base href="/">
    ...(lines omitted)
    
      System.import('main.js').catch(function(err){ console.error(err); });
    
  </head>

  <body>
    <my-app>Loading AppComponent content here ...</my-app>
  </body>
</html>

Some javascript files are loaded, and a custom tag named my-app is used in the body. The my-app tag is defined in the following component:

src/app/app.component.ts

Angular’s most important

(container)# cat src/app/app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>`,
})
export class AppComponent  { name = 'World'; }

The component defines the HTML tag ‚my-app‘, tells Angular to load the text Hello {{name}} as level 1 heading. The variable in double-curly brackets is replaced by its definition in the AppComponent.

Step 8: Change Component

With following example, we can see that a change in the component file is detected immediately and the Appliction is changed accordingly:

(container)# sed -r -i 's/Angular/World/g' src/app/app.component.ts
[root@471dd514dbef quickstart]# [0] 4:07:24 PM - File change detected. Starting incremental compilation...
[1] [BS] Reloading Browsers...
[0] 4:07:24 PM - Compilation complete. Watching for file changes.
[1] 17.06.13 16:07:25 304 GET /index.html
[1] 17.06.13 16:07:25 304 GET /styles.css
[1] 17.06.13 16:07:25 304 GET /core-js/client/shim.min.js
[1] 17.06.13 16:07:25 304 GET /zone.js/dist/zone.js
[1] 17.06.13 16:07:25 304 GET /systemjs/dist/system.src.js
[1] 17.06.13 16:07:25 304 GET /systemjs.config.js
[1] 17.06.13 16:07:25 304 GET /main.js
[1] 17.06.13 16:07:25 304 GET /@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js
[1] 17.06.13 16:07:25 304 GET /systemjs-angular-loader.js
[1] 17.06.13 16:07:25 304 GET /@angular/compiler/bundles/compiler.umd.js
[1] 17.06.13 16:07:25 304 GET /@angular/core/bundles/core.umd.js
[1] 17.06.13 16:07:25 304 GET /@angular/common/bundles/common.umd.js
[1] 17.06.13 16:07:25 304 GET /@angular/platform-browser/bundles/platform-browser.umd.js
[1] 17.06.13 16:07:25 304 GET /app/app.module.js
[1] 17.06.13 16:07:25 304 GET /rxjs/Observable.js
[1] 17.06.13 16:07:25 304 GET /rxjs/observable/merge.js
[1] 17.06.13 16:07:25 304 GET /rxjs/operator/share.js
[1] 17.06.13 16:07:25 304 GET /rxjs/Subject.js
[1] 17.06.13 16:07:25 200 GET /app/app.component.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/root.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/toSubscriber.js
[1] 17.06.13 16:07:25 304 GET /rxjs/symbol/observable.js
[1] 17.06.13 16:07:25 304 GET /rxjs/operator/merge.js
[1] 17.06.13 16:07:25 304 GET /rxjs/operator/multicast.js
[1] 17.06.13 16:07:25 304 GET /rxjs/Subscriber.js
[1] 17.06.13 16:07:25 304 GET /rxjs/Subscription.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/ObjectUnsubscribedError.js
[1] 17.06.13 16:07:25 304 GET /rxjs/SubjectSubscription.js
[1] 17.06.13 16:07:25 304 GET /rxjs/symbol/rxSubscriber.js
[1] 17.06.13 16:07:25 304 GET /rxjs/Observer.js
[1] 17.06.13 16:07:25 304 GET /rxjs/observable/ArrayObservable.js
[1] 17.06.13 16:07:25 304 GET /rxjs/operator/mergeAll.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/isScheduler.js
[1] 17.06.13 16:07:25 304 GET /rxjs/observable/ConnectableObservable.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/isFunction.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/isArray.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/isObject.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/tryCatch.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/errorObject.js
[1] 17.06.13 16:07:25 304 GET /rxjs/util/UnsubscriptionError.js
[1] 17.06.13 16:07:26 304 GET /rxjs/observable/ScalarObservable.js
[1] 17.06.13 16:07:26 304 GET /rxjs/observable/EmptyObservable.js
[1] 17.06.13 16:07:26 304 GET /rxjs/OuterSubscriber.js
[1] 17.06.13 16:07:26 304 GET /rxjs/util/subscribeToResult.js
[1] 17.06.13 16:07:26 304 GET /rxjs/util/isPromise.js
[1] 17.06.13 16:07:26 304 GET /rxjs/symbol/iterator.js
[1] 17.06.13 16:07:26 304 GET /rxjs/InnerSubscriber.js

In the browser, „Hello Angular“ is automatically exchanged by „Hello World“. There is no need to reload the browser page manually:

To toggle back and to ‚Hello Angular‘, you can issue the command

(container)# sed -r -i 's/World/Angular/g' src/app/app.component.ts

Step 9: Change index file

In this step, we will demonstrate that also a change in the index file is detected automatically. For that, you either can add some HTML code before the <my-app> tag. Alternatively, the following command will do that for you:

(container)# sed -r -i 's/<my-app/<h1>TEST<\/h1><my-app/g' src/index.html

After the change is performed, the browser will detect the change and display:

Excellent!

Summary

We have learned how to create and deploy a simple Angular Hello World app in a Docker container by downloading an quickstart example from git. After installing the NPM packet manager, NPM has helped us to resolve all dependencies and start the service.

We could demonstrate the Angular two way binding: a change in the component’s model or a change in the HTML code has triggered an automatic reload of the page.

References

6 comments

Comments

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.