Practical Angular PDF
Practical Angular PDF
with Angular 8
This book will walk you through building several apps with
Angular while learning new concepts and practices along
the way. This book is beginners friendly and doesn’t
assume any prior experience with Angular. You’ll learn
Angular from scratch building easy and relatively more
complex apps step by step.
Ahmed Bouchefra
This book is for sale at http://leanpub.com/practical-angular
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean
Publishing process. Lean Publishing is the act of publishing an in-progress ebook
using lightweight tools and many iterations to get reader feedback, pivot until you
have the right book and build traction once you do.
Contents
Introduction to Angular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
What is TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Introducing Angular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Angular Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Angular Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Why Would you Use Angular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Getting Started with Angular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
A Primer on Angular CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Build your First Angular Web Application with Firebase and Bootstrap . . . . . 27
Setting up your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Installing Angular CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Creating an Angular Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Styling our Components with Bootstrap 4 . . . . . . . . . . . . . . . . . . . . . . . . 32
Angular Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Child & Nested Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Adding Firebase Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Securing the UI with Router Guards . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A book by https://techiediaries.com
CONTENTS
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Creating an Angular Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Adding an Angular Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
How the HttpClient.get() Method Works . . . . . . . . . . . . . . . . . . . . . . . . . 72
Creating an Angular Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Master HttpClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
How Can You Increase Development Speed with Mocking? . . . . . . . . . . . . 97
What We’ll Cover in This chapter? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Step 1 - Setting up Angular CLI 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Step 2 - Initializing a New Angular 8 Example Project . . . . . . . . . . . . . . . . 101
Step 3 - Setting up a (Fake) JSON REST API . . . . . . . . . . . . . . . . . . . . . . . . 102
Step 4 - Setting up Angular HttpClient in our Example Project . . . . . . . . . . 105
Step 5 - Creating Angular Components . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Step 6 - Adding Angular Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Step 7 - Styling the UI with Angular Material . . . . . . . . . . . . . . . . . . . . . . 108
Step 8 - Consuming the JSON REST API with Angular HttpClient . . . . . . . . . 110
Step 9 - Adding HTTP Error Handling with RxJS catchError() & HttpClient . . . 115
Step 10 - Retrying Failed HTTP Requests with RxJS retry() & HttpClient . . . . 117
Step 11 - Unsubscribing from HttpClient Observables with RxJS takeUntil() . 118
Step 12 - Adding URL Query Parameters to the HttpClient get() Method . . . . 120
Step 13 - Getting the Full HTTP Response with Angular HttpClient . . . . . . . 120
A book by https://techiediaries.com
CONTENTS
A book by https://techiediaries.com
Introduction to Angular
Before diving into the practical steps for developing your first web app(s) with Angular
from scratch, let’s first learn about the basics of Angular.
Throughout this book’s chapters, you’ll learn how to use Angular to build client-side
web applications for mobile and desktop.
You’ll learn:
• How to use the Angular CLI for quickly creating a front-end project, generating
components, pipes, directives, and services, etc.
• How to add routing and navigation using the Angular router.
• How to build and submit forms, using reactive and template-based approaches.
• How to use Angular Material for building professional-grade UIs.
This first chapter is an in-depth introduction to Angular aimed at new developers who
have little experience with JavaScript client-side frameworks and want to learn the
essential concepts of Angular.
What is TypeScript
TypeScript is not the first attempt to create a super-set of JavaScript but it’s by far
the most successful one. It provides powerful OOP (Object Oriented Programming)
features like inheritance interfaces and classes, a declarative style, static typing, and
Introduction to Angular 2
modules. Although many of these features are already in JavaScript they are different
as JS follows a prototypical-based OOP, not class-based OOP.
TS features make it easy for developers to create complex and large JavaScript apps
that are easier to main and debug.
TypeScript is a compiled language which means we’ll need to transpile it into JavaScript
to be able to run it in web browsers which do only understand one programming
language. Fortunately, the TS transpiler integrates well with the majority of build
systems and bundlers.
You can install the TypeScript compiler using npm and then you can call it by running
the tsc source-file.ts command from your terminal. This will generate a source-file.js
JavaScript file with the same name. You can control many aspects of the compilation
process using a tsconfig.json configuration file. We can specify the module system to
compile to and where to output the compiled file(s) etc.
For large projects, you need to use advanced tools like task runners like Gulp and
Grunt and code bundlers like the popular Webpack.
You can use grunt-typescript and gulp-typescript plugins for integrating TypeScript
with Gulp and Grunt which will allow you to pass the compiler options from your task
runners.
For Webpack, you can use the loader to work with TypeScript.
More often than not, you’ll need to use external JavaScript libraries in your project.
You’ll also need to use type definitions.
Type definitions are files that end with the .d.ts extension — They allow us to use
TypeScript interfaces created by other developers for different JavaScript libraries
to integrate seamlessly with TypeScript. These definitions are available from the
DefinitelyTyped registry, from where we can install them.
To install them you need to use Typings. It has its configuration file, which is called
typings.json, where you need configure to specify paths for type definitions.
Introducing Angular
AngularJS was the most popular client-side framework among JavaScript developers
A book by https://techiediaries.com
Introduction to Angular 3
for many years. Google introduced AngularJS in 2012. It’s based on a variation of the
very popular Model-View-Controller pattern which is called Model-View-*.
The AngularJS framework was built on top of JavaScript to decouple the business logic
of an application from the low-level DOM manipulation and create dynamic websites.
Developers could use it to either create full-fledged SPAs and rich web applications or
simply control a portion of a web page which makes it suitable for different scenarios
and developer requirements.
Data Binding
Among the powerful concepts that were introduced by AngularJS, is the concept of
data binding which enables the view to get automatically updated whenever the data
(the model layer) is changed and vice versa.
Directives
The concept of directives was also introduced by AngularJS, which allows developers
to create their own custom HTML tags i.e extend HTML.
Dependency Injection
Angular Concepts
Components
A book by https://techiediaries.com
Introduction to Angular 4
You can create a component by creating a TypeScript class and decorate with the
@Component decorator available from the Angular core package ( @angular/core)
A component’s view is built using a unique HTML template associated with the
component’s class and also a stylesheet file that’s used to style the HTML view.
We start by importing Component from the Angular Core package and we use it to
decorate a TypeScript class.
• selector: It’s used to call the component from an HTML template e.g. <app-component></app-compon
just like any other HTML tag.
• templateUrl: It’ used to specify the relative path to an HTML file that will be used
as the component’s template
• styleUrls: It’s an array that specifies one or more stylesheets that can be used to
style the component’s view.
An Angular’s component has a life-cycle from it’s creation to destruction. There are
many events that you can listen to for executing code at these events.
Services
Angular services are singleton TypeScript classes that have only one instance through-
out the app and its lifetime. They provide methods that maintain data from the start
of the application to its end.
A book by https://techiediaries.com
Introduction to Angular 5
A service is used to encapsulate the business logic that can be repeated in mu areas
of your code. This helps the developers to follow the DRY (Don’t Repeat Yourself)
software concept.
The service can be called by components and even other services in the app. It’s
injected in the component’s constructor via Dependency Injection.
Services are used to achieve DRY and separation of concerns into an Angular ap-
plication. Along with components, they help make the application into reusable and
maintainable pieces of code that can be separated and even used throughout other
apps.
Let’s suppose that your application has many components that need to fetch data
from a remote HTTP resource.
If you are making an HTTP call to fetch the remote resource from a server in your
component. This means that each component is repeating a similar code for getting
the same resource. Instead, you can use a service that encapsulates the part of the
code that only deals with fetching the remote resources (The server address and the
specific resource to fetch can be passed via parameters to a service method). Then
we can simply inject the service wherever we want to call the fetching logic. This is
what’s called Separation of Concerns that states that components are not responsible
for doing specific tasks (in our case fetch data), instead a service can do the task and
pass data back to the components.
Angular Libraries
Angular provides many libraries out of the box. Let’s see the most important ones:
HttpClient
Angular has its powerful HTTP client that can be used to make calls to remote API
servers so you don’t need to use external libraries like Axios for example or even
the standard Fetch API. The HttpClient is based on the old XMLHttpRequest interface
available in all major browsers.
A book by https://techiediaries.com
Introduction to Angular 6
Angular Router
The Angular router is a powerful client-side routing library that allows you to add
build SPAs or Single Page Apps. It provides advanced features such as multiple router
outlets, auxiliary paths, and nested routing.
Angular 7 didn’t add many features to the router, except for some warnings that notify
the user when routing is activated outside the zone.
Angular Forms
Angular provides developers with powerful APIs to create and work with forms
and two approaches that you can choose from when you are dealing with forms:
Template-based and model-based or reactive forms.
Angular Material
Angular Material is a modern UI library based on Google’s Material Design spec which
provides common internationalized and themable UI components that work across
the web, mobile, and desktop. It’s built by the Angular team and integrate well with
Angular ecosystem.
In Angular 7 (and v6 also), you can use CLI ng add command for quickly add the required
dependencies and configure Material into your project:
1 ng add @angular/material
Angular 7 has added new features to this library including drag and drop support
so you don’t need to use an external library anymore and also virtual scrolling
which allows you to efficiently scroll large set of items without performance issues,
particularly on mobile devices.
A book by https://techiediaries.com
Introduction to Angular 7
• It provides support for most platform and web browsers such as web, mobile, and
desktop.
• It’s powerful and modern with a complete ecosystem,
• It can be used to develop native mobile apps with frameworks such as Native-
Script and Ionic
• It’s convenient and can be used with Electron to develop native desktop apps etc.
• Angular provides you with the tools and also with powerful software design
patterns to easily manage your project.
• It’s using TypeScript instead of plain JavaScript, a strongly typed and OOP-based
language created by Microsoft which provides features like strong types, classes,
interfaces, and even decorators, etc.
• It’s batteries-included which means you don’t have to look for a separate tool for
different tasks. With Angular, you have built-in libraries for routing, forms, and
HTTP calls, etc. You have templates with powerful directives and pipes. You can
use the forms APIs to easily create, manipulate and validate forms.
• Angular uses RxJS which is a powerful reactive library for working with Observ-
ables.
• Angular is a component-based framework which means decoupled and re-usable
components are the basic building of your application.
• In Angular DOM, manipulation is abstracted with a set of powerful APIs.
• Angular is a powerful framework that can be also used to build PWAs (Progressive
Web Apps).
Now let’s see how we can start using the latest Angular 7 version.
Prior knowledge of Angular is not required for this tutorial series but you’ll need to
have a few requirements:
You can clone a quick-start Angular project from GitHub to generate a new project.
If you have Git installed on your system, simply run the following command:
A book by https://techiediaries.com
Introduction to Angular 8
In the next chapter, we’ll use the Angular CLI to generate our Angular front-end
project. It’s also the recommended way by the Angular team.
Developers can use different ways to start a new project; such as:
Requirements
This chapter has a few requirements. Angular CLI depends on Node.js so you need
to have Node and NPM — Node 8.9 or higher, together with NPM 5.5.1 — installed on
your development machine. The easy way is to go their official website and get the
appropriate installer for your operating system.
Now, just to make sure you have Node.js installed, open a terminal and run the
following command:
1 node -v
You should get the version of the installed Node.js 8.9+ platform.
A book by https://techiediaries.com
Introduction to Angular 9
The Angular CLI is a powerful command-line utility built by the Angular team to make
it easy for developers to generate Angular projects without dealing with the complex
Webpack configurations or any other tool. It provides a fully-featured tool for working
with your project from generating artifacts like components, pipes, and services to
serving and building production-ready bundles.
To use the Angular CLI — you first need to install it via the npm package manager. Head
over to your terminal and enter the following command:
Note: Depending on your npm configuration, you may need to add sudo to
install global packages.
A book by https://techiediaries.com
Introduction to Angular 10
After installing Angular CLI, you’ll have various commands at your disposal. Let’s start
by checking the version of the installed CLI:
1 $ ng version
A second command that you might need to run is the help command to get a complete
usage help:
1 $ ng help
A book by https://techiediaries.com
Introduction to Angular 11
You can use Angular CLI to quickly generate your Angular project by running the
following command in your terminal:
1 $ ng new frontend
frontend is the name of the project. You can obviously choose any valid name
for your project. I’m using frontend as a name for the front-end application.
As mentioned earlier, the CLI will prompt you if Would you like to add Angular routing?,
you can answer by y (Yes) or No which is the default option. It will also ask you for the
stylesheet format, you want to use (such as CSS). Choose your options and hit Enter
to continue.
A book by https://techiediaries.com
Introduction to Angular 12
After that, you’ll have your project created with the directory structure and a bunch
of configurations and source code files, mostly in TypeScript and JSON format. Let’s
see the role of each file:
• /e2e/: This folder contains end-to-end (simulating user behavior) tests of the
website.
• /node_modules/: All 3rd party libraries are installed to this folder using npm install.
• /src/: It contains the source code of the application. Most work will be done here.
– /app/: It contains modules and components.
– /assets/: It contains static assets like images, icons, and styles etc.
– /environments/: It contains the environment (production and development)
specific configuration files.
– browserslist: Needed by autoprefixer for CSS support.
– favicon.ico: The favicon.
– index.html: The main HTML file.
– karma.conf.js: The configuration file for Karma (a testing tool)
– main.ts: The main starting file from where the AppModule is bootstrapped.
– polyfills.ts: Polyfills needed by Angular.
– styles.css: The global stylesheet file for the project.
– test.ts: This is a configuration file for Karma
A book by https://techiediaries.com
Introduction to Angular 13
Angular CLI provides a complete tool-chain for developing front-end apps on your
local machine. As such, you don’t need to install a local server to serve your project —
you can simply, use the ng serve from your terminal to serve your project locally.
First, navigate inside your project’s folder and run the following commands:
1 $ cd frontend
2 $ ng serve
You can now navigate to the http://localhost:4200/ address to start playing with your
front-end application. The page will automatically live-reload if you change any of the
source files.
You can also use a different host address and port other than the default ones by using
the --host and --port switches. For example:
A book by https://techiediaries.com
Introduction to Angular 14
account-list is the name of the component. You can also use just g instead
of generate The Angular CLI will automatically add a reference to components,
directives and pipes in the src/app/app.module.ts file.
If you want to add your component, directive or pipe to another module, other than
the main application module, you can simply prefix the name of the component with
the module name and a slash like a path:
1 $ ng g component account-module/account-list
Conclusion
Thanks to Angular CLI, you can get started with Angular by quickly generating a new
project with a variety of flags to customize and control the generation process. As a
recap, we have seen various ways to create a new Angular project.
We have also seen some of the important new features of all Angular versions up to
v8 and the basic concepts of Angular.
In the next chapter, you’ll start building your first Angular web application.
A book by https://techiediaries.com
Building a Calculator App with
Angular
In this chapter, you will learn to build your first Angular application from scratch.
You’ll get started with the basic concepts like modules, components, and directives.
You’ll also learn about event and property bindings. We’ll be building a simple
calculator application to demonstrate all these concepts.
Prerequisites
Let’s get started with the prerequisites. You will need to have:
After setting up your environment by installing Node and Angular CLI in your system,
let’s create a project. So open a terminal and execute the following command:
1 $ ng new ngcalculator
The CLI will ask you if you would like to add routing to your project - You can say No
as we will not need routing in this demo. For the stylesheets format, choose CSS.
You can then wait for the CLI to generate your project and install the required
dependencies from npm.
After that, you can start a live development server using the ng serve command:
Building a Calculator App with Angular 16
1 $ cd ./ngcalculator
2 $ ng serve
Wait for the CLI to compile your project and start the server at http://localhost:4200.
Angular follows a modular and component-based architecture. In fact, these are two
separate concepts:
• The modular architecture in which you build your application as a set of modules.
The general rule is that you need to use a module for each feature of your
application.
• The component-based architecture in which, you build your application as a set
of components.
Note: In our Angular project generated with the CLI, we already have a root
module which is conventionally called AppModule and a root component which
is conventionally called AppComponent.
The root module and component are the first things bootstrapped by the
Angular application (In the main.js and app.module.ts files)
Angular apps are modular and Angular has its own modularity system
called NgModules. NgModules are containers for a cohesive block of code
dedicated to an application domain, a workflow, or a closely related set
of capabilities. They can contain components, service providers, and other
code files whose scope is defined by the containing NgModule. They can
import functionality that is exported from other NgModules, and export
selected functionality for use by other NgModules.
Since we are building a simple calculator application we don’t need more than one
module, so let’s keep it simple and use the root module for implementing our feature.
Note: You can generate a new module using the CLI: ng generate module <name>.
A book by https://techiediaries.com
Building a Calculator App with Angular 17
A component controls a part of the screen. It’s simply a TypeScript class (decorated
with @Component) with an HTML template that displays the view.
We also don’t need many components in our calculator app. Let’s create one compo-
nent for encapsulating the calculator view and logic.
Open a new terminal, navigate to your project’s folder and run the following com-
mand:
We added the --skipTests option to tell the CLI to skip generating a file for component
tests as we will not add any tests in this tutorial.
The CLI has generated the following files in the src/app/calculator folder:
A book by https://techiediaries.com
Building a Calculator App with Angular 18
The CalculatorComponent class knows about the template and CSS file thanks to the
@Component() decorator which takes the following metadata:
• selector that allows us to give the component a tag name that can be used to
reference the component from other templates just like standard HTML tags.
• templateUrl that points to the HTML template that renders the view of the
component. You can also use an inline template with the template property
instead.
• styleUrls that allows us to associate one or multiple stylesheets to our compo-
nent.
Since we didn’t include routing in our application, we need a way to access our
calculator component from our root component. That’s where the selector property
of the component comes handy - we can call our calculator component using the
<app-calculator> tag. Open the src/app/app.component.html file, remove the existing
content and add:
1 <app-calculator></app-calculator>
We’ll be using the HTML and CSS code from this JS fiddle to create our calculator UI.
1 <div class="calculator">
2
3 <input type="text" class="calculator-screen" value="0" disabled />
4
5 <div class="calculator-keys">
6
7 <button type="button" class="operator" value="+">+</button>
8 <button type="button" class="operator" value="-">-</button>
9 <button type="button" class="operator" value="*">×</button>
10 <button type="button" class="operator" value="/">÷</button>
11
12 <button type="button" value="7">7</button>
13 <button type="button" value="8">8</button>
A book by https://techiediaries.com
Building a Calculator App with Angular 19
<script src=”https://gist.github.com/techiediaries/c5f68e66acbca784cb2350863aa4e4f0.js”></scr
We also need to add some global styling, so open the src/styles.css file and add:
1 html {
2 font-size: 62.5%;
3 box-sizing: border-box;
4 }
5
6 *, *::before, *::after {
7 margin: 0;
8 padding: 0;
9 box-sizing: inherit;
10 }
Now if you go to your web browser and navigate to your app, you should see the
following interface:
A book by https://techiediaries.com
Building a Calculator App with Angular 20
Now, we need to use the Angular magic to turn this template to a working calculator.
A book by https://techiediaries.com
Building a Calculator App with Angular 21
Up until now, our template is just plain HTML but Angular provides other constructs
that we can use in the templates such as data binding (interpolation, event and
property binding).
Simply put, data binding is a fundamental concept in Angular that allows developers
to make communication between a component and its view or more precisely the
DOM. This way you don’t need to manually push data from your component to the
DOM and back.
Angular provides four types of data binding and they are essentially different in the
way data flows i.e from the component to the DOM, from the DOM to the component
or both ways:
• Interpolation: Data flows from the component to the DOM - It’s used to display
the value of a component member variable in the associated template, e.g. {{
foobar }}. We use curly braces for interpolation.
• Property binding: Data flows from the component to a property of an element
in the DOM. It’s used to bind a component member variable to an attribute of a
DOM such as the value attribute of an <input> tag (For example: <input type="text"
[value]="foobar">). We use brackets for property binding.
• Event binding: Data flows from the DOM to the component. When a DOM event,
such as a click, is triggered, the bound method from the component is called. For
example: <button (click)="sayHi()">Hi</button> - The sayHi() method will be called
so it needs to be defined in the component class. We use parentheses for event
binding.
• Two-way data binding: Data flows both ways. For example: <input type="text"
[(ngModel)]="foobar"> (The foobar variable needs to be defined in the component).
The input element and foobar will have the same value and when one changes,
the other one changes to the same value accordingly. We use the banana in the
box syntax which combines brackets and parentheses for two-way data binding.
ngModel is a special directive that binds to the value attribute of the <input> and
<textarea> elements but you can construct two-way data binding for any property
in the DOM or component. Two-way data binding = property binding + event
binding.
We have DOM elements for operations and numbers and where to display the result
of the operation(s).
We need to get the value of the number or the type of the operation when the user
clicks on the corresponding DOM element, calculate the result and display it in the
results element.
A book by https://techiediaries.com
Building a Calculator App with Angular 22
• digits (0-9),
• operators (+, -, *, /, =),
• a decimal point (.)
• and a reset key.
Let’s see how we can use Angular to listen for clicks on the calculator and determine
what type of key was pressed.
• The currentNumber variable holds the string that will be displayed in the result input
element.
• The firstOperand variable holds the value of the first operand of the operation.
• The operator variable holds the operation.
• The waitForSecondNumber variable holds a boolean value indicating if the user has
finished typing the first operand and ready to enter the second operand of the
operation.
Next, define the getNumber() method that will be used to get the current number:
A book by https://techiediaries.com
Building a Calculator App with Angular 23
Next, define the getDecimal() method which appends the decimal point to the current
number:
1 getDecimal(){
2 if(!this.currentNumber.includes('.')){
3 this.currentNumber += '.';
4 }
5 }
Next, define the doCalculation() method which performs the calculation depending
on the operator type:
Next, define the getOperation() that will be used to get the performed operation:
A book by https://techiediaries.com
Building a Calculator App with Angular 24
13 this.waitForSecondNumber = true;
14
15 console.log(this.firstOperand);
16
17 }
Finally, define the clear() method that will be used to clear the result area and reset
the calculations:
1 public clear(){
2 this.currentNumber = '0';
3 this.firstOperand = null;
4 this.operator = null;
5 this.waitForSecondNumber = false;
6 }
Now, you need to use data binding to bind these methods to the template.
We have defined variables and methods in the component. Now, we’ll need to bind
them to the template.
Let’s start with the currentNumber variable which holds the value of the currently typed
number. Let’s use property binding to bind currentNumber to the value attribute of the
<input> element as follows:
1 <div class="calculator">
2
3 <input type="text" class="calculator-screen" [value]="currentNumber" disabled />
4
5 <!-- [...] -->
Now, our current number will be displayed in our calculator and when the value of the
currentNumber variable changes, the displayed value will change accordingly without
having to manually add any code to update the DOM.
A book by https://techiediaries.com
Building a Calculator App with Angular 25
Next, when a digit button is clicked we need to call the getNumber() method to append
the digit to the current number string. For this, we can use Angular event binding to
bind the getNumber() method to the click event of buttons displaying the digits. Change
your component template as follows:
1 <div class="calculator">
2
3 <input type="text" class="calculator-screen" [value]="currentNumber" disabled />
4
5 <div class="calculator-keys">
6
7 <!-- [...] -->
8
9 <button type="button" (click) = "getNumber('7')" value="7">7</button>
10 <button type="button" (click) = "getNumber('8')" value="8">8</button>
11 <button type="button" (click) = "getNumber('9')" value="9">9</button>
12
13
14 <button type="button" (click) = "getNumber('4')" value="4">4</button>
15 <button type="button" (click) = "getNumber('5')" value="5">5</button>
16 <button type="button" (click) = "getNumber('6')" value="6">6</button>
17
18
19 <button type="button" (click) = "getNumber('1')" value="1">1</button>
20 <button type="button" (click) = "getNumber('2')" value="2">2</button>
21 <button type="button" (click) = "getNumber('3')" value="3">3</button>
22
23
24 <button type="button" (click) = "getNumber('0')" value="0">0</button>
25 <!-- [...] -->
26 </div>
27 </div>
We use the parentheses around the click event to create an event binding.
Next, let’s bind the getOperation(), getDecimal() and clear() methods to the click event
of their respective buttons:
A book by https://techiediaries.com
Building a Calculator App with Angular 26
1 <div class="calculator-keys">
2
3 <button type="button" (click) = "getOperation('+')" class="operator" value="+">+\
4 </button>
5 <button type="button" (click) = "getOperation('-')" class="operator" value="-">-\
6 </button>
7 <button type="button" (click) = "getOperation('*')" class="operator" value="*">&\
8 times;</button>
9 <button type="button" (click) = "getOperation('/')" class="operator" value="/">&\
10 divide;</button>
11
12 <!-- [...] -->
13
14 <button type="button" (click) = "getDecimal()" class="decimal" value=".">.</butt\
15 on>
16 <button type="button" (click) = "clear()" class="all-clear" value="all-clear">A\
17 C</button>
18
19 <button type="button" (click) = "getOperation('=')" class="equal-sign" value="="\
20 >=</button>
21
22 </div>
23 </div>
Conclusion
In this chapter, we’ve built a simple calculator application with Angular. We’ve learned
about the types of data bindings and we’ve seen examples of event and property
binding in Angular.
A book by https://techiediaries.com
Build your First Angular Web
Application with Firebase and
Bootstrap
In this chapter, we’ll be covering Angular from scratch with routing and navigation by
building a complete example.
You will be building a simple web application that you can use to show your portfolio
projects and which you can host in the web and make it accessible to your potential
clients. You’ll use Firebase for authentication, Firestore for storing and fetching the
projects and Bootstrap 4 for styling the UI.
You’ll learn about the prerequisites for working with Angular, how to install Angular
CLI and use it to create your project and the various artifacts that you’ll need
throughout the development of your project.
You’ll learn how to work with route parameters, child routes, and nested routing.
You’ll learn about the router-outlet component, used by the Angular router to render
the component(s) matching the current path. How to navigate using the routerLink
and routerLinkActive directives or also the router navigate() method.
You’ll also learn about the router events, animations and the router resolve property
for fetching data.
You’ll also learn how to create Angular modules to organize your code, create
components for controlling various UI parts, add CRUD operations and style the UI
with Bootstrap 4.
You’ll start the tutorial by installing Angular CLI, the official CLI for creating and
working with Angular projects and workspaces, next you’ll generate your project
based on the latest version as of this writing, next you’ll proceed to create your app’s
pages and components.
Build your First Angular Web Application with Firebase and Bootstrap 28
After that, you’ll set up Bootstrap 4 in your project and style your Angular components
with the Bootstrap UI components. Finally, you’ll set up routing in your project and
add navigation between the various components composing your application.
Prerequisites
To follow along with this chapter, you need a few prerequisites, such as:
Let’s start by installing Angular CLI from npm using the following command:
As of the time of this writing, this will install angular cli v8 globally on your system.
We’ll start with the first step which is creating a new Angular project using the Angular
CLI. Head over to your terminal and run the following command:
1 $ ng new angular-portfolio
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 29
Now, you need to pay attention to this step — The Angular CLI will prompt you if you
Would like to add Angular routing? Answer by y (No is the default option) to tell the
CLI to generate the necessary files for routing like the src/app/app-routing.module.ts
file with all the required code for setting up the router. It will also add a <router-outlet>
component inside the src/app/app.component.html file which is where the router ren-
ders any matched component(s) depending on the current path.
Note: The Angular CLI will also prompt you to choose the stylesheets format
you want to use in your projects such as CSS, SCSS, Less, Stylus and Sass.
You can simply choose CSS if you prefer no other format.
That’s it. If you manage to pass this step without any errors you will have an Angular
project set up with best practices and routing all done automatically by the CLI on
your behalf.
Angular uses components everywhere so to have multiple pages, you need to create
components. You can also use components for specific parts of your page(s) that can
be unique in each page or common between multiple pages.
For example, we could have a home, about and contact components that represent
the corresponding pages and header and footer components that are common
between all the other components so we’ll create them once and have Angular
load them all the time whatever the current path is by simply adding them to our
application shell which is simply the main application component with the associated
src/app/app.component.html template that hosts <router-outlet>:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 30
Head back to your terminal, navigate inside your project’s root folder and run these
commands to create the components:
1 $ cd angular-portfolio
2 $ ng g c header
3 $ ng g c footer
4 $ ng g c home
5 $ ng g c about
6 $ ng g c contact
The CLI will generate the files for these components and the minimal required code
for declaring each component and its corresponding template.
For example, for the header component, the CLI will create the src/app/header/header.component.html,
src/app/header/header.component.spec.ts, src/app/header/header.component.ts and src/app/header/header
files.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 31
Those components will be imported and added in the main application module in the
src/app/app.module.ts file by the CLI in your behalf.
The previous components will be public i.e they could be accessed from any visitor of
your web application but let’s suppose we want to be able to list our latest portfolio
projects in our home page. We want to add the portfolio items from a protected admin
page that will be only accessed from the admin of the web application.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 32
For styling our components we’ll be using Bootstrap 4. The most popular CSS frame-
work in the world. In your terminal run the following command to install Bootstrap 4
from npm:
Note: This will install bootstrap v4.2.1 as the time of this tutorial.
1 "styles": [
2 "src/styles.css",
3 "./node_modules/bootstrap/dist/css/bootstrap.min.css"
4 ],
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 33
Next, you need to add the header component to the application shell. Open the
src/app/app.component.html file and update it accordingly:
1 <app-header></app-header>
2 <div class="container">
3 <router-outlet></router-outlet>
4 </div>
You include a component in other components using the selector property of the
@Component decorator:
At this point, we can serve our application using the following command:
1 $ ng serve
You can then see your application up and running by visiting the localhost:4200
address in your web browser.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 34
We want to load our home, about, contact and admin components when we click on
the links on the navigation header.
First we need to assign the components to their corresponding paths. You need to
open the src/app-routing.module.ts file and add the following imports:
1 // [...]
2 import { HomeComponent } from './home/home.component';
3 import { AboutComponent } from './about/about.component';
4 import { ContactComponent } from './contact/contact.component';
Next in the same file, add paths to various components inside the already-declared
routes array:
Each object in the array defines a route. The path property contains the path that will
be used to access a component and the component property contains the name of the
component.
Next we need to add navigation in our header component. Open the src/app/header/header.component.
file and update it with the convenient links using the routerLink directive:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 35
Recap
As a recap of what you achieved, you have installed Angular CLI and created a project
for your developer portfolio web application, you have setup routing and Bootstrap
4 in your project then created the various pages (components that represent whole
pages of your app and linked to unique routes) and components of your application
and created the routes and navigation links.
In the next section, you’ll learn about modules including the existing modules in your
project and you’ll create a feature module for encapsulating the code of the admin
part of your application.
Angular Modules
Angular modules are containers of code parts that implement related domain require-
ments. They let developers create apps with a modular architecture and reusable code
just like components. Angular uses NgModules to create modules and submodules
which are different from JavaScript/ES6 modules.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 36
What’s a NgModule
NgModules are simply TypeScript classes decorated with the @NgModule decorator
imported from the @angular/core package.
Modules provide a way for developers to organize their code and they are particularly
helpful for managing large apps.
You can either create your modules or use the built-in modules for importing the
various Angular APIs such as:
Each Angular module can contain components, directives, pipes, and services and
may be lazy-loaded by the router.
Your Angular application has at least one module which is called the root module. You
need to bootstrap the root module to start your application.
Now, let’s create the admin CRUD interface for listing, creating, updating and deleting
the portfolio projects.
• ProjectComponent,
• ProjectListComponent,
• ProjectCreateComponent,
• ProjectUpdateComponent.
1 $ ng g module admin
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 37
Next, run the following commands to create the components inside the admin
module:
1 $ ng g c admin/project-list
2 $ ng g c admin/project-create
3 $ ng g c admin/project-update
4 $ ng g c admin/project
• The components, directives, and pipes that belong to the module. In our case, the
four components that we created i.e ProjectListComponent, ProjectCreateComponent,
ProjectUpdateComponent and ProjectComponent.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 38
• The components, directives, and pipes that we want to export. In our case, none.
• The modules that we need to import in our current module. In our case CommonModule
• The services that we need to use. In our case none.
CommonModule is a built in module that exports all the basic Angular directives and
pipes, such as [NgIf](https://angular.io/api/common/NgIf), [NgForOf](https://angular.io/api/common/NgF
[DecimalPipe](https://angular.io/api/common/DecimalPipe), etc.
Next, we need to import the admin module in the main module. Open the src/app/app.module.ts
file and update it accordingly:
1 // [...]
2 import { AdminModule } from './admin/admin.module';
3
4 @NgModule({
5 // [...]
6 imports: [
7 BrowserModule,
8 AppRoutingModule,
9 AdminModule
10 ],
11 providers: [],
12 bootstrap: [AppComponent]
13 })
14 export class AppModule { }
This is the main module of our application. In the imports array, we added AdminModule.
You can see two other arrays:
• The providers array which can be used to include the services we want to provide
to our components,
• The bootstrap array which specifies the component(s) to bootstrap.
Recap
In this section, you have learned about the concept of NgModule in Angular, you
have created the admin submodule of your portfolio web application and the various
components of the submodule which are needed to build a CRUD interface for
creating and manipulating your portfolio’s projects.
In your next section, you’ll be adding routing in your admin module using a nested
router outlet and child routes.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 39
In the previous section, you have seen what NgModule is and you created the admin
module of your developer’s portfolio web application. Now, let’s add routing to our
module using a routing module, a nested router-outlet and child routes.
You can create a nested routing by defining child routes using the children property
of a route (alongside a path and component properties). You also need to add a nested
router-outlet in the HTML template related to the component linked to the parent
route (In our case it’s the admin route).
To create nested routing, you need to create a routing submodule for the module you
want to provide routing for, you next need to define a parent route and its child routes
and provide them to the router configuration via a forChild() method.
Let’s see this, step by step. First, inside the admin module, create an admin-routing.module.ts
file and add a submodule for implementing child routing in our admin module:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 40
25 }
26 ]
27 }
28 ];
29 @NgModule({
30 imports: [RouterModule.forChild(routes)],
31 exports: [RouterModule]
32 })
33 export class AdminRoutingModule { }
This is an example of a module which has imports and exports meta information;
• The imports array which contains the modules that we need to import and use in
the current module. In this case it’s RouterModule.forChild(routes),
• The exports array which contains what we need to export.
To provide our child routes to the router module, we use the forChild() method of the
module because we want to add routing in the admin submodule. if this is used in the
root module you need to use the forRoot() method instead. See more differences of
forChild() vs forRoot() from the official docs.
The forChild() and forRoot() methods are static methods that are used to configure
modules in Angular. They are not specific to RouterModule.
We are creating a parent admin route and its child routes using the children property
of the route which takes an array of routes.
Next, open the src/app/admin/admin.module ts file and import the routing module:
1 // [..]
2 import { AdminRoutingModule } from './admin-routing.module';
3
4 @NgModule({
5 // [...]
6 imports: [
7 CommonModule,
8 AdminRoutingModule
9 ]
10 })
11 export class AdminModule { }
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 41
Next open the src/app/admin/project/project.component html file and add a nested router
outlet:
1 <h2>Admin Interface</h2>
2 <router-outlet></router-outlet>
This is a nested router-outlet that will be only used to render the components of the
admin module i.e ProjectListComponent, ProjectCreateComponent and ProjectCreateComponent.
Note: If you don’t add a nested router outlet in the parent route, child
components will be rendered in the parent router outlet of the application.
1 <li class="nav-item">
2 <a class="nav-link" routerLink="/admin/list">Admin</a>
3 </li>
At this point, if you click on the admin link in the header, you should see the following
interface:
Recap
In this section, you have added nested routing in your Angular application by creating
a routing submodule for the admin module and adding a nested router-outlet and
child routes for the /admin parent route.
In the next section, you’ll secure the admin interface using Firebase authentication
with email and password.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 42
In the previous section, you have added routing to your admin module. You will now
add email and password authentication with Firebase.
Note: Since we only need to allow admin access to the portfolio owner we
only need to provide the login and logout functionality in our application
without allowing registration. A user with email and password will be man-
ually created in our Firebase console.
If you don’t already have a Firebase setup, you simply need to head to your Firebase
console and click on Add project then follow the steps to create a Firebase project:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 43
Enter a name for your project, accept the terms and click on the blue Create project
button:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 44
Once your project is created, you need to click on it to go to the admin dashboard for
that particular project.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 45
On the dashboard, go to Develop > Authentication and click on the Web setup button:
Click on the Copy button to copy all code with your credentials in your clipboard:
1 <script src="https://www.gstatic.com/firebasejs/5.7.1/firebase.js"></script>
2 <script>
3 // Initialize Firebase
4 var config = {
5 apiKey: "YOUR_API_KEY",
6 authDomain: "YOUR_AUTH_DOMAIN",
7 databaseURL: "YOUR_DATABASE_URL",
8 projectId: "YOUR_PROJECT_ID",
9 storageBucket: "YOUR_STORAGE_BUCKET",
10 messagingSenderId: "YOUR_MESSAGING_SENDER_ID"
11 };
12 firebase.initializeApp(config);
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 46
13 </script>
In our case, we only need the values of the config object because we’ll be installing
Firebase SDK from npm.
Next, you’ll need to enable Email authentication from the authentication > Sign-in
method tab:
When you click on the Set up sign-in method button, you’ll be takin to the following
tab:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 47
One last thing that you need to do from the console is creating a user with email
and password that you’ll use to login because we will not allow registration from our
web application. Only the website admin will be able to access the admin interface to
create their portfolio.
Go to the authentication > Users tab and click on the Add user button:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 48
Enter your user’s credentials and click on the Add user button:
Installing AngularFire2
Head back to your terminal, make sure your are inside your project’s root folder and
run the following command to install Firebase SDK and AngularFire2 from npm:
Once the library is installed, you need to add it to your application main module. Open
the src/app/app.module.tsfile and update it accordingly:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 49
1 // [...]
2 import { AngularFireModule } from "@angular/fire";
3 import { AngularFireAuthModule } from "@angular/fire/auth";
4
5 var config = {
6 apiKey: "YOUR_API_KEY",
7 authDomain: "YOUR_AUTH_DOMAIN",
8 databaseURL: "YOUR_DATABASE_URL",
9 projectId: "YOUR_PROJECT_ID",
10 storageBucket: "YOUR_STORAGE_BUCKET",
11 messagingSenderId: "YOUR_MESSAGING_SENDER_ID"
12 };
13
14 @NgModule({
15 imports: [
16 AngularFireModule.initializeApp(config),
17 AngularFireAuthModule
18 ]
19 })
After setting up Firebase authentication in our project using AngularFire2 v5, we’ll
now proceed to create a login UI.
Previously, we have created the admin module with a bunch of components to create,
update and list the developer’s portfolio projects. Now, let’s create one more compo-
nent for user login. In your terminal, run this command:
1 $ ng g c admin/login
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 50
1 // [...]
2 import { LoginComponent } from './login/login.component';
3
4 const routes: Routes = [
5 {
6 path: 'admin',
7 component: ProjectComponent,
8
9 children: [
10 // [...]
11 { path: 'login',component: LoginComponent}
12 ]
13 }
14 ];
All these routes are children of the admin route. So, for example, you can access the
login page from the http://127.0.0.1:4200/admin/login route:
Firebase login
To abstract all the interactions with Firebase authentication, we will create an Angular
service using this command:
1 $ ng g s auth/auth.service
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 51
Next, inject the Firebase authentication service and the router via the service’s
constructor:
1 @Injectable({
2 providedIn: 'root'
3 })
4 export class AuthService {
5 user: User;
6 constructor(public afAuth: AngularFireAuth, public router: Router) { }
7 }
Next, in the constructor, we subscribe to the authentication state; if the user is logged
in, we add the user’s data to the browser’s local storage; otherwise, we store a null user
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 52
1 this.afAuth.authState.subscribe(user => {
2 if (user) {
3 this.user = user;
4 localStorage.setItem('user', JSON.stringify(this.user));
5 } else {
6 localStorage.setItem('user', null);
7 }
8 })
Next, add the login() method that will be used to login users with email and password:
1 async logout(){
2 await this.afAuth.auth.signOut();
3 localStorage.removeItem('user');
4 this.router.navigate(['admin/login']);
5 }
Next, add the isLoggedIn() property to check if the user is logged in:
We are done with the authentication service. Next, we need to create the login and
register UIs.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 53
Open the src/app/admin/login/login.component.ts file and import then inject the au-
thentication service:
Next open the the src/app/admin/login/login.component.html file and add the following
HTML code:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 54
21 </div>
22 </div>
23 </div>
24 </div>
25 </div>
Let’s also add some styling for adding a shadow to the form in the src/app/admin/login/login.component
file:
1 .card {
2 box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
3 }
If you visit the http://localhost:4200/admin/login address, you’ll see the following UI:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 55
Recap
In this section, you have seen how you can add email and password authentication in
your web application using Google’s Firebase.
In the next section, you’ll use Angular 7 guards to protect the admin interface
from unauthorized access i.e you will only be able to activate the route if you have
successfully logged in with your email and password that you provided when you
created a user in the Firebase console.
In the previous section, we have added routing in our developer portfolio web
application created with Angular 7. Let’s now secure the UI with router guards.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 56
We’ll be learning how to use Router Guards and UrlTree data structures to protect the
UI if the user is not logged in and redirect them to the login interface if they don’t
have access to a specific route.
The admin interface can be only accessed by the website admin so we need to use
Guards to protect the components of the admin module and only allow access to
them if the user is logged in.
First, you need to create a guard. Run the following command in your terminal to
generate a guard service:
1 $ ng g guard admin/admin
Note: We prefix the guard name with the admin/ path to generate it inside the
admin folder for the matter of code organization.
From the code, you see that a guard is simply a service that implements the CanActivate
interface and overrides the canActivate() method. In this case, it always returns true
which means access will be always granted to the user when this guard is applied to
a route.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 57
Let’s change the method to only allow access if the user is logged in. First, you need
to import AuthService and inject it via the AdminGuard service and next you need to call
the isLoggedIn property in the canActivate() method to check if the user is logged in
and return true or false;
The canActivate() method will return true if the user is logged in or false otherwise.
The canActivate() method is passed many arguments which makes it easy to determine
if the guard needs to allow or disallow access to certain route(s):
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 58
Now, you need to apply the guard to the routes you need to protect using the
canActivate property of the path object. Open the src/app/admin/admin-routing.module.ts
file and update it accordingly:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 59
40 @NgModule({
41 imports: [RouterModule.forChild(routes)],
42 exports: [RouterModule]
43 })
44 export class AdminRoutingModule { }
Note: The canActivate property of the path object takes an array which means
you can register multiple guards.
Before Angular 7.1, route guards can only return a boolean, Promise<boolean> or Observable<boolean>
(asynchronous boolean objects) to tell the router if the route can be activated or not.
But now, you can also return an UrlTree variable which provides the new router state
(route) that should be activated.
According to the Angular docs an UrlTree is a data structure that represents a parsed
URL.
Now, let’s change our router guard to redirect the users to the /admin/login route if
they try to access the protected admin components without being logged in first:
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 60
We check if the user is logged in and we return true, otherwise, we return the result
from the parseUrl("/admin/login") method of the injected router instance which is an
UrlTree of the /admin/login route.
Now, go to your application, if you visit any protected route without logging in you
will be redirected to the /admin/login route where you can log in.
Recap
As a recap, we’ve seen how to use route guards new feature introduced in Angular
v7.1+ which enables you to redirect to another route by using a UrlTree parsed route.
In this section, we’ve used Angular Guards and UrlTree structures that correspond to
parsed routes to disallow access to certain routes if users are not logged in.
A book by https://techiediaries.com
Build your First Angular Web Application with Firebase and Bootstrap 61
In the next section, we’ll proceed by implementing the CRUD operations of the admin
interface which allow the portfolio owner to add projects to their website. We’ll be
using Firestore as our persistence layer.
A book by https://techiediaries.com
Build a Contact Form with Angular
In this chapter, we’ll learn how to build and work with forms in Angular by creating a
simple contact form example.
For small projects, there is no better approach, just choose the one most convenient
to you!
For bigger projects, it’s recommended to use reactive forms as they scale better.
Check out this in-depth article for more information.
You can register for an account using your GitHub account and START A NEW APP
based on Angular from ready templates. Your Angular project will be based on the
latest Angular version.
Now, let’s start with the template-based approach by building an example form. Let’s
do some configurations.
Open the src/app/app.module.ts file and import the FormsModule then we add it to the
imports array:
Build a Contact Form with Angular 63
That’s all that you need to add to be able to work with template-based forms.
Next, open the src/app/app.component.html file and add the following content:
We can create our form completely in our template. We first add a template reference
variable to the form and assign the ngForm key to it using the #myform = "ngForm" syntax.
This will allow us to access the form via the myform reference.
Note: The #myform = "ngForm" syntax doesn’t create a template-based form but
only a local template variable that will allow us to work with the form object.
In fact, the form was automatically created when you imported FormsModule
in your project.
A book by https://techiediaries.com
Build a Contact Form with Angular 64
Next, we bind the ngSubmit event to the onSubmit() method (Which we’ll add to our
component next) and we pass in the form object (via the local template variable)
Next, we register the child controls with the form. We simply add the NgModel
directive and a name attribute to each element.
Next, add the onSubmit() method to the component. Open the src/app/app.component.ts
file and add the following code:
We passed in the reference to the NgForm object that represents our form to the
onSubmit() method and we can use it to access various properties like value which
provides a plain JS object that contains the attributes of the form and their values.
In this example, we simply print the form value in the console but in a real-world
situation, we can use it to send the data to a server via a POST request.
You can see all the available methods of NgForm from the docs.
After, adding some CSS styles from this pen, this is a screenshot of our form UI:
A book by https://techiediaries.com
Build a Contact Form with Angular 65
Angular
A book 8 Form
by https:/ Example
/techiediaries.com
Build a Contact Form with Angular 66
After building our contact form with the template-based approach, let’s now see how
we can build the same example with the reactive based approach.
1 // [...]
2
3 @NgModule({
4 imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
5 declarations: [ AppComponent ],
6 bootstrap: [ AppComponent ]
7 })
8 export class AppModule { }
Next, open the src/app/app.component.ts file and import FormGroup and FormBuilder:
Next, define the contactForm variable which will be used to hold our form object
(instance of FormGroup) and inject FormBuilder via the component constructor:
A book by https://techiediaries.com
Build a Contact Form with Angular 67
1 createContactForm(){
2 this.contactForm = this.formBuilder.group({
3 fullName: [''],
4 email: [''],
5 message: ['']
6 });
7 }
We call the group() method of the injected instance of FormBuilder to create a FormGroup
of three controls, fullName, email and message. Each control can take an optional array
of options and validation rules.
Finally, add the following method which will be called when we submit our form:
1 onSubmit() {
2 console.log('Your form data : ', this.contactForm.value );
3 }
Now, we need to bind this form object to our HTML form. Open the src/app/app.component.html
file and add the following code:
A book by https://techiediaries.com
Build a Contact Form with Angular 68
14 <br/>
15 <input type = "submit" value = "Send">
16 </form>
We use property binding to bind the form using the formGroup property. Next, we
use formControlName to sync the FormControl objects in contactForm with the HTML form
controls by name. See the docs for more details. Finally, we bind the ngSubmit event of
the form to the onSubmit() method.
Conclusion
In this chapter, we’ve built an example contact form in Angular 8 using the template-
based approach and the reactive (model-based) approach
A book by https://techiediaries.com
Building a News App with Angular -
HttpClient
In this tutorial, you’ll learn by example how to send GET requests to REST API servers
in your Angular application using HttpClient. We’ll also learn how to use the basic
concepts of Angular like components and services and how to use the ngFor directive
to display collections of data.
Throughout this chapter, we are going to build a simple example from scratch using
Angular CLI and we’ll see how to use HttpClient to send GET requests to third-party
REST API servers and how to consume and display the returned JSON data.
Prerequisites
Before getting started, you need a few requirements. You need to have the following
tools installed on your development machine:
• Node.js and npm. You can install both of them from the official website.
• Angular CLI (You can install it from npm using: npm install -g @angular/cli)
Now let’s create our Angular project. Open a new terminal and run the following
command:
Building a News App with Angular - HttpClient 70
1 $ ng new angular-httpclient-demo
The CLI will prompt you if Would you like to add Angular routing? (y/N), type y. And
Which stylesheet format would you like to use? Choose CSS and type Enter.
Next, you can serve your application locally using the following commands:
1 $ cd ./angular-httpclient-demo
2 $ ng serve
Before you can fetch the news data from NewsAPI.org which offers a free plan for open
source and development projects, you first need to go the register page for getting
an API key.
Next, let’s create a service that will take care of getting data from the news API. Open
a new terminal and run the following command:
Setting up HttpClient
Next, open the src/app/app.module.ts file then import HttpClientModule and add it to the
imports array:
A book by https://techiediaries.com
Building a News App with Angular - HttpClient 71
1 // [...]
2 import { HttpClientModule } from '@angular/common/http';
3
4 @NgModule({
5 declarations: [AppComponent],
6 entryComponents: [],
7 imports: [
8 // [...]
9 HttpClientModule,
10 ],
11 // [...]
12 })
13 export class AppModule {}
That’s all, we are now ready to use the HttpClient in our project.
Next, open the src/app/api.service.ts file and inject HttpClient via the service con-
structor:
Next, define an API_KEY variable which will hold your API key from the News API:
A book by https://techiediaries.com
Building a News App with Angular - HttpClient 72
Finally, add a method that sends a GET request to an endpoint for TechCrunch news:
1 public getNews(){
2 return this.httpClient.get(`https://newsapi.org/v2/top-headlines?sources=techcru\
3 nch&apiKey=${this.API_KEY}`);
4 }
The HttpClient get() method is designed to send HTTP GET requests. The syntax is
as follows:
It takes a REST API endpoint and an optional options object and returns an Observable
instance.
Now, let’s create an Angular 8 component for displaying the news data. Head back to
your terminal and run the following command:
A book by https://techiediaries.com
Building a News App with Angular - HttpClient 73
Next, define an articles variable and call the getNews() method of the API service in
the ngOnInit() method of the component:
This will make sure our data is fetched once the component is loaded.
We call the getNews() method and subscribe to the returned Observable which will
send a GET request to the news endpoint.
A book by https://techiediaries.com
Building a News App with Angular - HttpClient 74
Let’s now display the news articles in our component template. Open the src/app/news.component.html
file and update it as follows:
Angular CLI 8 has automatically added routing for us, so we don’t need to set up
anything besides adding the component(s) to our Router configuration. Open the
src/app/app-routing.module.ts file and start by importing the news component as
follows:
You can now access your component from the /news path.
A book by https://techiediaries.com
Building a News App with Angular - HttpClient 75
Conclusion
In this chapter, we used Angular to build a simple news application that retrieves
data from a JSON REST API using the get() method of HttpClient. We’ve seen how to
subscribe to the RxJS Observable returned from the get() method and how to use the
*ngFor directive to iterate over the fetched data in the template.
A book by https://techiediaries.com
Building a Full-Stack App with
Angular, PHP and MySQL
In this chapter, you’ll create an example REST API CRUD Angular application with PHP
and a MySQL backend.
You will be creating a simple RESTful API that supports GET, POST, PUT and DELETE
requests and allow you to perform CRUD operations against a MySQL database to
create, read, update and delete records from a database.
For the application design, It’s a simple interface for working with vehicle insurance
policies. For the sake of simplicity, you are only going to add the following attributes
to the policies database table:
This is of course far from being a complete database design for a fully working
insurance system. Because at least you need to add other tables like employees,
clients, coverage, vehicles, and drivers, etc. And also the relationships between all
these entities.
Prerequisites
Also read PHP Image/File Upload Tutorial and Example [FormData and
Angular 7 Front-End]
Let’s start by creating a simple PHP script that connects to a MySQL database and
listens to API requests then responds accordingly by either fetching and returning
data from the SQL table or insert, update and delete data from the database.
Go ahead and create a folder structure for your project using the following commands:
1 $ mkdir angular-php-app
2 $ cd angular-php-app
3 $ mkdir backend
We create the angular-php-app that will contain the full front-end and back-end
projects. Next, we navigate inside it and create the backend folder that will contain
a simple PHP script for implementing a simple CRUD REST API against a MySQL
database.
Next, navigate into your backend project and create an api folder.
1 $ cd backend
2 $ mkdir api
1 $ cd api
2 $ touch database.php
3 $ touch read.php
4 $ touch create.php
5 $ touch update.php
6 $ touch delete.php
Open the backend/api/database.php file and add the following PHP code step by step:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 78
1 <?php
2 header("Access-Control-Allow-Origin: *");
3 header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE");
4 header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\
5 ");
These lines are used to add response headers such as CORS and the allowed methods
(PUT, GET, DELETE and POST).
Setting CORS to * will allow your PHP server to accept requests from another domain
where the Angular 7 server is running from without getting blocked by the browser
because of the Same Origin Policy. In development, you’ll be running the PHP server
from localhost:8080 port and Angular from localhost:4200 which are considered as two
distinct domains.
Next, add:
1 define('DB_HOST', 'localhost');
2 define('DB_USER', 'root');
3 define('DB_PASS', 'YOUR_PASSWORD');
4 define('DB_NAME', 'mydb');
These variables hold the credentials that will be used to connect to the MySQL
database and the name of the database.
Note: Make sure you change them to your actual MySQL credentials. Also
make sure you have created a database with a policies table that has two
number and amount columns.
Next, add:
1 function connect()
2 {
3 $connect = mysqli_connect(DB_HOST ,DB_USER ,DB_PASS ,DB_NAME);
4
5 if (mysqli_connect_errno($connect)) {
6 die("Failed to connect:" . mysqli_connect_error());
7 }
8
9 mysqli_set_charset($connect, "utf8");
10
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 79
11 return $connect;
12 }
13
14 $con = connect();
This will allow you to create a connection to the MySQL database using the mysqli
extension.
Now, let’s implement the read operation. Open the backend/api/read.php file and add
the following code:
1 <?php
2 /**
3 * Returns the list of policies.
4 */
5 require 'database.php';
6
7 $policies = [];
8 $sql = "SELECT id, number, amount FROM policies";
9
10 if($result = mysqli_query($con,$sql))
11 {
12 $i = 0;
13 while($row = mysqli_fetch_assoc($result))
14 {
15 $policies[$i]['id'] = $row['id'];
16 $policies[$i]['number'] = $row['number'];
17 $policies[$i]['amount'] = $row['amount'];
18 $i++;
19 }
20
21 echo json_encode($policies);
22 }
23 else
24 {
25 http_response_code(404);
26 }
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 80
This will fetch the list of policies from the database and return them as a JSON
response. If there is an error it will return a 404 error.
Let’s now implement the create operation. Open the backend/api/create.php file and
add the following code:
1 <?php
2 require 'database.php';
3
4 // Get the posted data.
5 $postdata = file_get_contents("php://input");
6
7 if(isset($postdata) && !empty($postdata))
8 {
9 // Extract the data.
10 $request = json_decode($postdata);
11
12
13 // Validate.
14 if(trim($request->number) === '' || (float)$request->amount < 0)
15 {
16 return http_response_code(400);
17 }
18
19 // Sanitize.
20 $number = mysqli_real_escape_string($con, trim($request->number));
21 $amount = mysqli_real_escape_string($con, (int)$request->amount);
22
23
24 // Create.
25 $sql = "INSERT INTO `policies`(`id`,`number`,`amount`) VALUES (null,'{$number}','{\
26 $amount}')";
27
28 if(mysqli_query($con,$sql))
29 {
30 http_response_code(201);
31 $policy = [
32 'number' => $number,
33 'amount' => $amount,
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 81
1 <?php
2 require 'database.php';
3
4 // Get the posted data.
5 $postdata = file_get_contents("php://input");
6
7 if(isset($postdata) && !empty($postdata))
8 {
9 // Extract the data.
10 $request = json_decode($postdata);
11
12 // Validate.
13 if ((int)$request->id < 1 || trim($request->number) == '' || (float)$request->amou\
14 nt < 0) {
15 return http_response_code(400);
16 }
17
18 // Sanitize.
19 $id = mysqli_real_escape_string($con, (int)$request->id);
20 $number = mysqli_real_escape_string($con, trim($request->number));
21 $amount = mysqli_real_escape_string($con, (float)$request->amount);
22
23 // Update.
24 $sql = "UPDATE `policies` SET `number`='$number',`amount`='$amount' WHERE `id` = '\
25 {$id}' LIMIT 1";
26
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 82
27 if(mysqli_query($con, $sql))
28 {
29 http_response_code(204);
30 }
31 else
32 {
33 return http_response_code(422);
34 }
35 }
1 <?php
2
3 require 'database.php';
4
5 // Extract, validate and sanitize the id.
6 $id = ($_GET['id'] !== null && (int)$_GET['id'] > 0)? mysqli_real_escape_string($con\
7 , (int)$_GET['id']) : false;
8
9 if(!$id)
10 {
11 return http_response_code(400);
12 }
13
14 // Delete.
15 $sql = "DELETE FROM `policies` WHERE `id` ='{$id}' LIMIT 1";
16
17 if(mysqli_query($con, $sql))
18 {
19 http_response_code(204);
20 }
21 else
22 {
23 return http_response_code(422);
24 }
In all operations, we first require the database.php file for connecting to the MySQL
database and then we implement the appropriate logic for the CRUD operation.
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 83
You can next serve your PHP application using the built-in development server using
the following command:
In your terminal, run the following command to start the MySQL client:
1 $ mysql -u root -p
The client will prompt for the password that you configured when installing MySQL
in your system.
Next create the policies SQL table with two number and amount columns:
1 mysql> create table policies( id int not null auto_increment, number varchar(20), am\
2 ount float, primary key(id));
Now, you are ready to send GET, POST, PUT and DELETE requests to your PHP server
running from the 127.0.0.1:8080 address.
For sending test requests, you can use REST clients such as Postman or cURL before
creating the Angular UI.
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 84
Wrap-up
In this section, you have created a PHP RESTful API that can be used to execute CRUD
operations against a MySQL database to create, read, update and delete insurance
policies.
You have enabled CORS so you can use two domains localhost:8000 and localhost:4200
for respectively serving your PHP and Angular apps and being able to send requests
from Angular to PHP without getting blocked by the Same Origin Policy rule in modern
web browsers.
In this section, you’ll learn how to use HttpClient to make HTTP calls to a REST API
and use template-based forms to submit data.
Now, that you’ve created the RESTful API with a PHP script, you can proceed to create
your Angular project.
The recommended way of creating Angular projects is through using Angular CLI, the
official tool created by the Angular team. The latest and best version yet is Angular
CLI 8 so head back to another terminal window and run the following command to
install the CLI:
Note: This will install Angular CLI globally so make sure you have configured
npm to install packages globally without adding sudo in Debian systems and
macOS or using an administrator command prompt on Windows. You can
also just fix your npm permissions if you get any issues
That’s it! You can now use the CLI to create an Angular project using the following
command:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 85
1 $ cd angular-php-app
2 $ ng new frontend
The CLI will ask you if Would you like to add Angular routing? type y because we’ll
need routing setup in our application. And Which stylesheet format would you like
to use? Select CSS.
Wait for the CLI to generate and install the required dependencies and then you can
start your development server using:
1 $ cd frontend
2 $ ng serve
You can access the frontend application by pointing your browser to the http://localhost:4200
address.
Angular provides developers with a powerful HTTP client for sending HTTP requests
to servers. It’s based on the XMLHttpRequest interface supported on most browsers and
has a plethora of features like the use of RxJS Observable instead of callbacks or
promises, typed requests and responses and interceptors.
You can set up HttpClient in your project by simply importing the HttpClientModule in
your main application module.
Open the src/app/app.module.ts file and import HttpClientModule then ad it to the imports
array of @NgModule:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 86
That’s it! You can now use HttpClient in your components or services via dependency
injection.
Let’s now, create an Angular service that will encapsulate all the code needed for
interfacing with the RESTful PHP backend.
Open a new terminal window, navigate to your frontend project and run the following
command:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 87
We inject HttpClient as a private httpClient instance via the service constructor. This
is called dependency injection. If you are not familiar with this pattern. Here is the
definition from Wikipedia:
Also, this is what Angular docs says about dependency injection in Angular:
You can now use the injected httpClient instance to send HTTP requests to your PHP
REST API.
Create a policy.ts file in the src/app folder of your project and add the following
TypeScript class:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 88
Next, open the src/app/api.service.ts file and import the Policy model and the RxJS
Observable interface:
Next, add the readPolicies() method that will be used to retrieve the insurance policies
from the REST API endpoint via a GET request:
1 readPolicies(): Observable<Policy[]>{
2 return this.httpClient.get<Policy[]>(`${this.PHP_API_SERVER}/api/read.php`);
3 }
Next, add the createPolicy() method that will be used to create a policy in the database:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 89
1 updatePolicy(policy: Policy){
2 return this.httpClient.put<Policy>(`${this.PHP_API_SERVER}/api/update.php`, poli\
3 cy);
4 }
Finally, add the deletePolicy() to delete policies from the SQL database:
1 deletePolicy(id: number){
2 return this.httpClient.delete<Policy>(`${this.PHP_API_SERVER}/api/delete.php/?id\
3 =${id}`);
4 }
After creating the service that contains the CRUD operations, let’s now create an
Angular component that will call the service methods and will contain the table to
display policies and a form to submit a policy to the PHP backend.
Let’s add this component to the Router. Open the src/app/app-routing.module.ts file
and add a /dashboard route:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 90
You can now access your dashboard component from the 127.0.0.1:4200/dashboard
URL. This is a screenshot of the page at this point:
Let’s remove the boilerplate content added by Angular CLI. Open the src/app/app.component.html
file and update accordingly:
1 <router-outlet></router-outlet>
We only leave the router outlet where Angular router will insert the matched compo-
nent(s).
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 91
Next, let’s define the policies array that will hold the insurance policies once we get
them from the server after we send a GET request and also the selectedPolicy variable
that will hold the selected policy from the table.
On the ngOnInit() method of the component, let’s call the readPolicies() method of
ApiService to get the policies:
1 ngOnInit() {
2 this.apiService.readPolicies().subscribe((policies: Policy[])=>{
3 this.policies = policies;
4 console.log(this.policies);
5 })
6 }
Note: The actual HTTP request is only sent to the server when you subscribe
to the returned Observable.
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 92
You should see the returned policies in your browser console. This is a screenshot of
the output in my case:
We’ll see a bit later how to display these policies in a table in the component template.
Let’s add the other methods to create, update and delete policies in our component.
1 createOrUpdatePolicy(form){
2 if(this.selectedPolicy && this.selectedPolicy.id){
3 form.value.id = this.selectedPolicy.id;
4 this.apiService.updatePolicy(form.value).subscribe((policy: Policy)=>{
5 console.log("Policy updated" , policy);
6 });
7 }
8 else{
9
10 this.apiService.createPolicy(form.value).subscribe((policy: Policy)=>{
11 console.log("Policy created, ", policy);
12 });
13 }
14
15 }
16
17 selectPolicy(policy: Policy){
18 this.selectedPolicy = policy;
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 93
19 }
20
21 deletePolicy(id){
22 this.apiService.deletePolicy(id).subscribe((policy: Policy)=>{
23 console.log("Policy deleted, ", policy);
24 });
25 }
Let’s now add a table and form to display and create the policies in our dashboard
component. Open the src/app/dashboard/dashboard.component.html and add the follow-
ing HTML code:
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 94
Next, below the table, let’s add a form that will be used to create and update a policy:
1 <br>
2 <form #f = "ngForm">
3 <label>Number</label>
4 <input type="text" name="number" [(ngModel)] = "selectedPolicy.number">
5 <br>
6 <label>Amount</label>
7 <input type="text" name="amount" [(ngModel)] = "selectedPolicy.amount">
8 <br>
9 <input type="button" (click)="createOrUpdatePolicy(f)" value="Create or Update P\
10 olicy">
11 </form>
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 95
1 input {
2 width: 100%;
3 padding: 2px 5px;
4 margin: 2px 0;
5 border: 1px solid red;
6 border-radius: 4px;
7 box-sizing: border-box;
8 }
9
10 button, input[type=button]{
11 background-color: #4CAF50;
12 border: none;
13 color: white;
14 padding: 4px 7px;
15 text-decoration: none;
16 margin: 2px 1px;
17 cursor: pointer;
18 }
19 th, td {
20 padding: 1px;
21 text-align: left;
22 border-bottom: 1px solid #ddd;
23
24 }
25 tr:hover {background-color: #f5f5f5;}
A book by https://techiediaries.com
Building a Full-Stack App with Angular, PHP and MySQL 96
Conclusion
In this chapter, we learned how to create a RESTful CRUD application with PHP,
MySQL, and Angular.
A book by https://techiediaries.com
Master HttpClient
In this chapter, we’ll learn how to use Angular HttpClient and RxJS in easy steps by
building an example web application that consumes a REST API.
The REST API will be mocked using json-server which allows you to create a fully-
working API based on a JSON file that contains sample data.
Introduction
More often than not, modern web development involves multiple developers working
in separate front-end and back-end applications. This approach has many advantages,
such as the separation of concerns but also introduces a few challenges such as the
difficulties in coordination between the front-end and back-end developers. Here
comes the role of tools such as JSON-Server to ease these difficulties.
Most of the times when we hear about mocking, we think of unit testing where we
need to mock an object instance before we’ll be able test it. But actually we can do
more with mocking beyond testing.
In this chapter, we’ll show you how you can increase your development speed and
quality by mocking. your backend.
In most cases, a project is developed by two front-end and back-end teams. When
a new project is started, we as front-end developers need to wait for the back-end
team to create a REST API that we can consume from our app. But how we can make
the two teams work in parallel?
A front-end app is mostly about the UI which needs data from the server. If you don’t
want to wait for the backend API to be ready, you need a way to mock HTTP data.
This, generally, can be done in two approaches:
Master HttpClient 98
• The backend developers prepare the stubs and simply return some hard-coded
data. This still requires some time before the frontend developers can start
working on the app.
• The frontend developers create and use hardcoded data which becomes messy
fast.
Both approaches have many disadvantages but luckily for Angular developers, there
is another way which involves using json-server to mock a fully-working REST API in
no time with nearly zero-lines of code in most scenarios.
As a front-end developer, JSON-Server is such a great tool that allows you to spin up
a REST API server with a fully-working API with zero coding.
In this chapter, we’ll show you how to use JSON-Server to simulate a REST API with
literally zero lines of code.
Angular 8 was released on May 28, 2019, and comes with various features and
improvements to the Angular CLI and the framework. We now have small bundles
and new APIs to hook into the ng add and ng build commands of the CLI but also a new
ng deploy command. This chapter is now updated to the latest Angular 8.3 version.
We’ll see how to use the new ng deploy feature in Angular 8.3+ to easily deploy your
Angular application from the command-line to Firebase hosting.
A book by https://techiediaries.com
Master HttpClient 99
• How to handle HTTP errors using the throwError() and catchError() operators,
• How to retry failed HTTP requests using the RxJS retry() operator,
• How to unsubscribe from RxJS Observables returned from HttpClient methods
using the takeUntil() operator when requests are concelled,
• How to build your application for production and deploy it to Firebase hosting
using the new ng deploy command available from Angular 8.3+
Prerequisites
A book by https://techiediaries.com
Master HttpClient 100
Note: If you don’t want to install a local environment for Angular develop-
ment but still want to try the code in this chapter, you can use Stackblitz, an
online IDE for frontend development that you can use to create an Angular
project compatible with Angular CLI.
If you have the previous prerequisites, you are ready for the next steps of our chapter
that will teach you by example how to use Angular HttpClient to send HTTP GET
requests for fetching JSON data and the various RxJS operators such as catchError(),
tap(), retry(), and takeUntil() for implementing advanced features such as error
handling, retrying failed HTTP requests and cancelling pending requests. In the first
step(s) of our chapter, we’ll see how to install Angular CLI 8 and create an example
project from scratch.
In this step, we’ll install the latest Angular CLI 8 version (at the time of writing this
chapter).
Angular CLI
Angular CLI is the official tool for initializing and working with Angular projects. To
install it, open a new command-line interface and run the following command:
A book by https://techiediaries.com
Master HttpClient 101
At the time of writing this chapter, angular/cli v8.3.2 will be installed on your system.
In the next step, we’ll learn how to intialize a new example project from the command-
line.
In this step, we’ll proceed to create our example project. Head back to your command-
line interface and run the following commands:
1 $ cd ~
2 $ ng new ngstore
The CLI will ask you a couple of questions - If Would you like to add Angular routing?
Type y for Yes and Which stylesheet format would you like to use? Choose CSS. This
will instruct the CLI to automatically set up routing in our project so we’ll only need
to add the routes for our components to implement navigation in our application.
Next, navigate to you project’s folder and run the local development server using the
following commands:
1 $ cd ngstore
2 $ ng serve
Open your web browser and navigate to the http://localhost:4200/ address to see your
app up and running. This is a screenshot at this point:
A book by https://techiediaries.com
Master HttpClient 102
Angular 8 Project
You should now leave the development server running and start a new command-line
interface for running the CLI commands of the next steps.
In the next step, we’ll learn how to create a fake JSON REST API that we’ll be consuming
in our Angular example application.
Before we proceed to develop our Angular application, we’ll need to prepare a JSON
REST API that we can consume using HttpClient.
We can also consume or fetch JSON data from third-party REST API servers but in this
example, we choose to create a fake REST API. Check out this tutorial for a real REST
API example. As far as Angular concerned, there is no difference between consuming
fake or real REST APIs.
As said, you can either use an external API service, create a real REST API server or
create a fake API using json-server. In this example we’ll use the last approach. So head
over to a new command-line interface and start by installing json-server from npm in
your project:
A book by https://techiediaries.com
Master HttpClient 103
1 $ cd ~/ngstore
2 $ npm install - save json-server
Next, create a server folder in the root folder of your Angular project:
1 $ mkdir server
2 $ cd server
In the server folder, create a database.json file and add the following JSON object:
1 {
2 "products": []
3 }
This JSON file will act as a database for your REST API server. You can simply add
some data to be served by your REST API or use Faker.js for automatically generating
massive amounts of realistic fake data.
Go back to your command-line, navigate back from the server folder, and install
Faker.js from npm using the following command:
1 $ cd ..
2 $ npm install faker - save
At the time of creating this example, faker v4.1.0 will be installed. Now, create a
generate.js file and add the following code:
A book by https://techiediaries.com
Master HttpClient 104
We first imported faker, next we defined an object with one empty array for products.
Next, we entered a for loop to create 300 fake entries using faker methods like
faker.commerce.productName() for generating product names. Check all the available
methods. Finally we converted the database object to a string and log it to standard
output.
Next, add the generate and server scripts to the package.json file:
1 "scripts": {
2 "ng": "ng",
3 "start": "ng serve",
4 "build": "ng build",
5 "test": "ng test",
6 "lint": "ng lint",
7 "e2e": "ng e2e",
8 "generate": "node ./server/generate.js > ./server/database.json",
9 "server": "json-server - watch ./server/database.json"
10 },
Next, head back to your command-line interface and run the generate script using
the following command:
Finally, run the REST API server by executing the following command:
You can now send HTTP requests to the server just like any typical REST API server.
Your server will be available from the http://localhost:3000/ address.
A book by https://techiediaries.com
Master HttpClient 105
These are the API endpoints we’ll be able to use via our JSON REST API server:
You can use _page and _limit parameters to get paginated data. In the Link header you’ll
get first, prev, next and last links.
For example:
GET /products?_page=1 for getting the first page of data, GET /products?_page=1&_limit=5
for getting the first five products of the first page of data.
Note: You can use other features such as filters, sorting and ordering. For
more information, check out the docs.
Leave the JSON REST API server running and open a new command-line interface for
typing the commands of the next steps.
As a summary of what we have done - We installed Angular CLI and initialized a new
project based on the latest Angular 8 version. Then, we created a REST API using
json-server based on a JSON file. In the next step of our chapter, we’ll learn how to set
up HttpClient in our Angular 8 project.
In this step, we’ll proceed to set up the HttpClient module in our example.
HttpClient lives in a separate Angular module, so we’ll need to import it in our main
application module before we can use it.
Open your example project with a code editor or IDE. We’ll be using Visual Studio
Code.
Next, open the src/app/app.module.ts file, import HttpClientModule and add it to the
imports array of the module as follows:
A book by https://techiediaries.com
Master HttpClient 106
That’s all, we are now ready to use the HttpClient service in our project but before that
we need to create a couple of components - The home and about components. This is
what we’ll learn to do in the next step.
In this step, we’ll proceed to create the Angular components that control our applica-
tion UI. Head back to a new command-line interface and run the following command:
1 $ cd ~/ngstore
2 $ ng generate component home
The CLI created four files for the component and added it to the declarations array in
the src/app/app.module.ts file.
Next, let’s create the about component using the following command:
A book by https://techiediaries.com
Master HttpClient 107
We’ll update the home component in the following steps. In the next step of our
chapter, we’ll add these components to the router.
We first imported the home and about components, next we added three routes
including a route for redirecting the empty path to the home component, so when
the user visits the app, they will be redirected to the home page.
In the next step of our example, we’ll set up Angular Material in our project for styling
our UI.
A book by https://techiediaries.com
Master HttpClient 108
In this step of our chapter, we’ll proceed to add Angular Material to our project and
style our application UI. Angular Material provides Material Design components that
allow developers to create professional UIs. Setting up Angular Material in our project
is much easier now with the new ng add command of the Angular CLI v7+. Head back to
your command-line interface, and run the following command from the root of your
project:
1 $ ng add @angular/material
You’ll be asked for choosing a theme, choose Indigo/Pink. For the other options - Set
up HammerJS for gesture recognition? and Set up browser animations for Angular
Material? Simply press Enter in your keyboard to choose the default answers.
1 @import "~@angular/material/prebuilt-themes/indigo-pink.css";
Each Angular Material component has a separate module that you need to import
before you can use the component. Open the src/app/app.module.ts file and add the
following imports:
1 import { MatToolbarModule,
2 MatIconModule,
3 MatCardModule,
4 MatButtonModule,
5 MatProgressSpinnerModule } from '@angular/material';
A book by https://techiediaries.com
Master HttpClient 109
1 @NgModule({
2 declarations: [
3 AppComponent,
4 HomeComponent,
5 AboutComponent
6 ],
7 imports: [
8 BrowserModule,
9 AppRoutingModule,
10 HttpClientModule,
11 BrowserAnimationsModule,
12 MatToolbarModule,
13 MatIconModule,
14 MatButtonModule,
15 MatCardModule,
16 MatProgressSpinnerModule
17 ],
18 providers: [],
19 bootstrap: [AppComponent]
20 })
21 export class AppModule { }
1 <mat-toolbar color="primary">
2 <h1>
3 ngStore
4 </h1>
5 <button mat-button routerLink="/">Home</button>
6 <button mat-button routerLink="/about">About</button>
7 </mat-toolbar>
8 <router-outlet></router-outlet>
We created the shell of our application containing a top bar with two navigation
buttons to the home and about components.
As a summary of what we did until this point of our chapter - We have setup HttpClient
and Angular Material in our project, created the home and about components and
configured routing, and finaly added the shell of our application containing a topbar
with navigation. In the next step of our chapter, we’ll learn how to fetch the JSON data
from our REST API server using HttpClient.
A book by https://techiediaries.com
Master HttpClient 110
In this step, we’ll proceed to consume JSON data from our REST API server in our
example application.
Front end applications, built using frameworks like Angular communicate with back-
end servers through REST APIs (which are based on the HTTP protocol) using either
the XMLHttpRequest interface or the fetch() API.
Angular HttpClient makes use of the XMLHttpRequest interface that supports both
modern and legacy browsers.
The HttpClient is available from the @angular/common/http package and has a sim-
plified API interface and powerful features such as easy testability, typed request
and response objects, request and response interceptors, reactive APIs with RxJS
Observables, and streamlined error handling.
• HttpClient makes it easy to send and process HTTP requests and responses,
• HttpClient has many builtin features for implementing test units,
• HttpClient makes use of RxJS Observables for handling asynchronous operations
instead of
A book by https://techiediaries.com
Master HttpClient 111
Now after introducing HttpClient, let’s proceed to building our example application
starting with the prerequisites needed to successfully complete the tutorial.
We’ll need to create an Angular service for encapsulating the code that deals with
consuming data from the REST API server.
A service is a singleton that can be injected by other services and components using
the Angular dependency injection.
Next, open the src/app/data.service.ts file, import and inject HttpClient as follows:
A book by https://techiediaries.com
Master HttpClient 112
The method simply invokes the get() method of HttpClient to send GET requests to
the REST API server.
Next, we now need to use this service in our home component. Open the src/app/home/home.component.
file, import and inject the data service as follows:
We imported and injected DataService as a private dataService instance via the compo-
nent constructor.
Next, we defined a products variable and called the sendGetRequest() method of the
service for fetching data from the JSON REST API server. Since the sendGetRequest()
A book by https://techiediaries.com
Master HttpClient 113
method returns the return value of the HttpClient.get() method which is an RxJS
Observable, we subscribed to the returned Observable to actually send the HTTP GET
request and process the HTTP response. When data is received, we added it in the
products array.
We used the <mat-spinner> component for showing a loading spinner when the length
of the products array equals zero i.e before no data is received from the REST API
server. Next, we iterated over the products array and used a Material card to display
the name, price, quantity, description and image of each product.
A book by https://techiediaries.com
Master HttpClient 114
Angular 8 Example
A book by https://techiediaries.com
Master HttpClient 115
In this step, we’ll proceed to add error handling in our example application.
The Angular’s HttpClient methods can be easily used with the catchError() operator
from RxJS, since they return Observables, via the pipe() method for catching and
handling errors. We simply need to define a method to handle errors within your
service.
• Client-side errors such as network issues and JavaScript syntax and type errors.
These errors return ErrorEvent objects.
• Server-side errors such as code errors in the server and database access errors.
These errors return HTTP Error Responses.
Now, let’s see this by example. Open the src/app/data.service.ts file and update it
accordingly:
A book by https://techiediaries.com
Master HttpClient 116
As you can see, this needs to be done for each service in your application which is
fine for our example since it only contains one service but once your application
starts growing with many services which may all throw errors you need to use better
solutions instead of using the handleError method per each service which is error-
prone. One solution is to handle errors globally in your Angular application using
HttpClient interceptors.
In the next step, we’ll see how to improve our data service by automatically retry
sending the failed HTTP requests.
A book by https://techiediaries.com
Master HttpClient 117
In this step of our chapter, we’ll see how to use the retry() operator of RxJS with
HttpClient to automatically resubscribing to the returned Observable which results
in resending the failed HTTP requests.
In many cases, errors are temporary and due to poor network conditions so simply
trying again will make them go away automatically. For example, in mobile devices
network interruptions are frequent so if the user tries again, they may get a successful
response. Instead of letting users manually retry, let’s see how to do that automatically
in our example application.
The RxJS library provides several retry operators. Among them is the retry() operator
which allows you to automatically re-subscribe to an RxJS Observable a specified
number of times. Re-subscribing to the Observable returned from an HttpClient
method has the effect of resending the HTTP request to the server so users don’t
need to repeat the operation or reload the application.
You can use the RxJS retry() operator by piping it (using the pipe() method) onto the
Observable returned from the HttpClient method before the error handler.
1 public sendGetRequest(){
2 return this.httpClient.get(this.REST_API_SERVER).pipe(retry(3), catchError(this.han\
3 dleError));
4 }
This will retry sending the failed HTTP request three times.
In the next step, we’ll see how to unsubscribe from RxJS Observables in our example
home component.
A book by https://techiediaries.com
Master HttpClient 118
In this step of our chapter, we’ll learn about why we need and how to unsubscribe
from Observables in our code using the takeUntil() operator.
First of all, do you need to unsubscribe from the Observables returned by the
HttpClient methods? Generally, you need to manually unsubscribe from any sub-
scribed RxJS Observables in your Angular components to avoid memory leaks but
in the case of HttpClient, this is automatically handled by Angular by unsubscribing
when the HTTP response is received. However, there are some cases when you need
to manually unsubscribe for example to cancel pending requests when users are about
to leave the component.
We can simply call the unsubscribe() method from the Subscription object returned by
the subscribe() method in the ngOnDestroy() life-cycle method of the component to
unsubscribe from the Observable.
There is also a better way to unsubscribe from or complete Observables by using the
takeUntil() operator.
The takeUntil() operator emits the values emitted by the source Observable until a
notifier Observable emits a value.
Let’s see how to use this operator to complete Observables when the component is
destroyed.
A book by https://techiediaries.com
Master HttpClient 119
14 ngOnInit() {
15 this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((data: an\
16 y[])=>{
17 console.log(data);
18 this.products = data;
19 })
20 }
21 ngOnDestroy() {
22 this.destroy$.next(true);
23 // Unsubscribe from the subject
24 this.destroy$.unsubscribe();
25 }
26 }
We first imported the OnDestroy interface, Subject and the takeUntil() operator. Next,
we implemented the OnDestroy interface and added the ngOnDestroy() lifecycle hook to
the component.
Next, we created an instance of Subject which can emit boolean values (the type of
the value doesn’t really matter in this example) that will be used as the notifier of the
takeUntil() operator.
Next, in the ngOnInit() lifecycle hook, we called the sendGetRequest() of our data service
and called the pipe() method of the returned Observable to pipe the takeUnitl()
operator and finaly subscribed to the combined Observable. In the body of the
subscribe() method, we added the logic to put the fetched data of the HTTP response
in the products array. The takeUntil() operator allows a notified Observable to emit
values until a value is emitted from a notifier Observable.
When Angular destroys a component it calls the ngOnDestroy() lifecycle method which,
in our case, calls the next() method to emit a value so RxJS completes all subscribed
Observables. That’s it. In this step, we have added the logic to cancel any pending
HTTP request by unsubscribing from the returned Observable in case the user
descides to navigate away from the component before the HTTP response is received.
In the next step of our chapter, we’ll see how to use URL query parameters with the
get() method of HttpClient.
A book by https://techiediaries.com
Master HttpClient 120
In this step, we’ll start adding the logic for implementing pagination in our example
application.
We’ll see how to use URL query parameters via fromString and HttpParams to provide the
appropriate values for the the _page and _limit parameters of the /products endpoint
of our JSON REST API server for getting paginated data.
Open the src/app/data.service.ts file and start by adding the following the import for
HttpParams:
We used HttpParams and fromString to create HTTP query parameters from the _-
page=1&_limit=20 string. This tells to returns the first page of 20 products.
Now the sendGetRequest() will be used to retrieve the first page of data. The received
HTTP response will contain a Link header with information about the first, previous,
next and last links of data pages.
In the Link header you’ll get first, prev, next and last links. In the next step, we’ll see
how to extract these pagination links by parsing full HTTP responses.
In this ste, we’ll proceed by implementing the logic for retrieving pagination informa-
tion from the Link header contained in the HTTP response received from the JSON
REST API server.
By default, HttpClient does only provide the response body but in our case we need to
parse the Link header for pagination links so we need to tell HttpClient that we want
the full HttpResponse using the observe option.
A book by https://techiediaries.com
Master HttpClient 121
The Link header in HTTP allows the server to point an interested client to an-
other resource containing metadata about the requested resource.Wikipedia
Next, define the parseLinkHeader() method which parses the Link header and populate
the previous variables accordingly:
1 parseLinkHeader(header) {
2 if (header.length == 0) {
3 return ;
4 }
5 let parts = header.split(',');
6 var links = {};
7 parts.forEach( p => {
8 let section = p.split(';');
9 var url = section[0].replace(/<(.*)>/, '$1').trim();
10 var name = section[1].replace(/rel="(.*)"/, '$1').trim();
11 links[name] = url;
12 });
13
14 this.first = links["first"];
15 this.last = links["last"];
16 this.prev = links["prev"];
17 this.next = links["next"];
18 }
A book by https://techiediaries.com
Master HttpClient 122
1 public sendGetRequest(){
2 // Add safe, URL encoded _page and _limit parameters
3
4 return this.httpClient.get(this.REST_API_SERVER, { params: new HttpParams({fromStri\
5 ng: "_page=1&_limit=20"}), observe: "response"}).pipe(retry(3), catchError(this.hand\
6 leError), tap(res => {
7 console.log(res.headers.get('Link'));
8 this.parseLinkHeader(res.headers.get('Link'));
9 }));
10 }
We added the observe option with the response value in the options parameter of the
get() method so we can have the full HTTP response with headers. Next, we use the
RxJS tap() operator for parsing the Link header before returning the final Observable.
Since the sendGetRequest() is now returning an Observable with a full HTTP response,
we need to update the home component so open the src/app/home/home.component.ts
file and import HttpResponse as follows:
1 ngOnInit() {
2 this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((res: Htt\
3 pResponse<any>)=>{
4 console.log(res);
5 this.products = res.body;
6 })
7 }
We can now access the data from the body object of the received HTTP response. Next,
go back to the src/app/data.service.ts file and add the following method:
A book by https://techiediaries.com
Master HttpClient 123
This method is similar to sendGetRequest() except that it takes the URL to which we
need to send an HTTP GET request.
Go back to the src/app/home/home.component.ts file and add define the following meth-
ods:
1 public firstPage() {
2 this.products = [];
3 this.dataService.sendGetRequestToUrl(this.dataService.first).pipe(takeUntil(this.de\
4 stroy$)).subscribe((res: HttpResponse<any>) => {
5 console.log(res);
6 this.products = res.body;
7 })
8 }
9 public previousPage() {
10 if (this.dataService.prev !== undefined && this.dataService.prev !== '') {
11 this.products = [];
12 this.dataService.sendGetRequestToUrl(this.dataService.prev).pipe(takeUntil(this.des\
13 troy$)).subscribe((res: HttpResponse<any>) => {
14 console.log(res);
15 this.products = res.body;
16 })
17 }
18 }
19 public nextPage() {
20 if (this.dataService.next !== undefined && this.dataService.next !== '') {
21 this.products = [];
22 this.dataService.sendGetRequestToUrl(this.dataService.next).pipe(takeUntil(this.des\
23 troy$)).subscribe((res: HttpResponse<any>) => {
24 console.log(res);
25 this.products = res.body;
26 })
27 }
A book by https://techiediaries.com
Master HttpClient 124
28 }
29 public lastPage() {
30 this.products = [];
31 this.dataService.sendGetRequestToUrl(this.dataService.last).pipe(takeUntil(this.des\
32 troy$)).subscribe((res: HttpResponse<any>) => {
33 console.log(res);
34 this.products = res.body;
35 })
36 }
Finally, add open the src/app/home/home.component.html file and update the template as
follows:
A book by https://techiediaries.com
Master HttpClient 125
A book by https://techiediaries.com
Master HttpClient 126
In this step, we’ll see how to use typed HTTP responses in our example application.
Angular HttpClient allows you to specify the type of the response object in the request
object, which make consuming the response easier and straightforward. This also
enables type assertion during the compile time.
Let’s start by defining a custom type using a TypeScript interface with the required
properties. Head back to your command-line interface and run the following com-
mand from the root of your project:
Next, specify the Product interface as the HttpClient.get() call’s type parameter in
the data service. Go back to the src/app/data.service.ts file and import the Product
interface:
Next:
A book by https://techiediaries.com
Master HttpClient 127
1 public sendGetRequest(){
2 return this.httpClient.get<Product[]>(this.REST_API_SERVER, { params: new HttpParams\
3 ({fromString: "_page=1&_limit=20"}), observe: "response"}).pipe(retry(3), catchError\
4 (this.handleError), tap(res => {
5 console.log(res.headers.get('Link'));
6 this.parseLinkHeader(res.headers.get('Link'));
7
8 }));
9 }
10 public sendGetRequestToUrl(url: string){
11 return this.httpClient.get<Product[]>(url, { observe: "response"}).pipe(retry(3), c\
12 atchError(this.handleError), tap(res => {
13 console.log(res.headers.get('Link'));
14 this.parseLinkHeader(res.headers.get('Link'));
15
16 }));
17 }
Next, open the src/app/home/home.component.ts file and import the Product interface:
Next chnage the type of the HTTP response in the sendGetRequest() call:
1 ngOnInit() {
2 this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((res: Htt\
3 pResponse<Product[]>) => {
4 console.log(res);
5 this.products = res.body;
6 })
7 }
You also need to do the same for the other firstPage(), previousPage(), nextPage() and
lastPage() methods.
A book by https://techiediaries.com
Master HttpClient 128
In this step, we’ll see how to build and deploy our example application to Firebase
hosting using the ng deploy command available in Angular 8.3+.
We’ll only see how to deploy the frontend application without the fake JSON server.
Angular CLI 8.3+ introduced a new ng deploy command that makes it more easier than
before to deploy your Angular application using the deploy CLI builder assocaited
with your project. There are many third-party builders that implement deployment
capabilities for different platforms. You can add any of them to your project by running
the ng add command.
Let’s now see that by example by deploying our project to Firebase hosting.
Head back to your command-line interface, make sure you are inside the root folder
of your Angular project and run the following command:
1 $ ng add @angular/fire
The command will also update the package.json of our project by adding this section:
1 "deploy": {
2 "builder": "@angular/fire:deploy",
3 "options": {}
4 }
The CLI will prompt you to Paste authorization code here: and will open your default
web browser and ask you to give Firebase CLI permissions to administer your Firebase
account:
A book by https://techiediaries.com
Master HttpClient 129
A book by https://techiediaries.com
Master HttpClient 130
After you signin with the Google account associated with your Firebase account, you’ll
be given the authorization code:
Next, you’ll be prompted: Please select a project: (Use arrow keys or type to search).
You should have created a Firebase project before.
The CLI will create the firebase.json and .firebaserc files and update the angular.json
file accordingly.
A book by https://techiediaries.com
Master HttpClient 131
1 $ ng deploy
The command will produce an optimized build of your application (equivalent to the
ng deploy - prod command), it will upload the production assets to Firebase hosting.
Conclusion
Throughout this chapter, we’ve built a complete working Angular application example
using the latest Angular 8.3+ version.
You learned to mock a REST API backend for your Angular application with nearly
zero-lines of code.
You learned to create a project using Angular CLI, add HttpClient and Angular Material
for sending HTTP requests to your mocked REST API backend and styling the UI with
Material Design components.
You have particularly seen how send HTTP GET requests with parameters using the
get() method, how to handle HTTP errors using the RxJS throwError() and catchError()
operators, unsubscribe from RxJS Observables for the cancelled HTTP requests using
the takeUntil() operator and retry failed requests with the retry() operator.
Finally, you learned to deploy your Angular application to Firebase using the ng deploy
command available starting from Angular 8.3+.
A book by https://techiediaries.com