FullStack UNIT 4
FullStack UNIT 4
NAGAVENI
UNIT-IV
Express and Angular
1
FULLSTACK NOTES N.NAGAVENI
2
FULLSTACK NOTES N.NAGAVENI
In fact, the value returned by express() is actually a callback function that maps to the
callback function that is passed into
the http.createServer() and https.createServer() methods.
To illustrate this, illustrates implementing a basic HTTP and HTTPS server using Node.js.
Notice that the app variable returned from express() is passed into
the createServer() methods. Also, notice that an options object is defined to set the host, key,
and cert used to create the HTTPS server. Lines 13–15 implement a simple get route that
handles the / path.
express_http_https.js: Implementing HTTP and HTTPS servers using Express
01 var express = require('express');
02 var https = require('https');
03 var http = require('http');
04 var fs = require('fs');
05 var app = express();
06 var options = {
07 host: '127.0.0.1',
08 key: fs.readFileSync('ssl/server.key'),
09 cert: fs.readFileSync('ssl/server.crt')
10 };
11 http.createServer(app).listen(80);
12 https.createServer(options, app).listen(443);
13 app.get('/', function(req, res){
14 res.send('Hello from Express');
15 });
Configuring Routes
The previous section discussed how to start the Express HTTP server. However, before the
server can begin accepting requests, you need to define routes.
A route is simply a definition that describes how to handle the path portion of the URI in the
HTTP request to the Express server.
Implementing Routes
There are two parts when defining the route.
First is the HTTP request method (typically GET or POST). Each of these methods often
needs to be handled completely differently.
3
FULLSTACK NOTES N.NAGAVENI
Second, is the path specified in the URL—for example, / for the root of the
website, /login for the login page, and /cart to display a shopping cart.
The express module provides a series of functions that allow you to implement routes for the
Express server. These functions all use the following syntax:
app.<method>(path, [callback . . .], callback)
The <method> portion of the syntax actually refers to the HTTP request method, such
as GET or POST. For example:
app.get(path, [middleware, ...], callback)
app.post(path, [middleware, ...], callback)
The path refers to the path portion of the URL that you want to be handled by
the callback function.
The middleware parameters are 0 or more middleware functions that are applied before
executing the callback function.
The callback function is the request handler that handles the request and sends the response
back to the client. The callback function accepts a Request object as the first parameter and
a Response object as the second.
For example, the following code implements some basic GET and POST routes:
app.get('/', function(req, res){
res.send("Server Root");
});
app.get('/login', function(req, res){
res.send("Login Page");
});
app.post('/save', function(req, res){
res.send("Save Page");
});
When the Express server receives an HTTP request, it looks for a route that has been defined
for the appropriate HTTP method and path. If one is found, a Request and Response object is
created to manage the request and is passed into the callback function(s) for the route.
Express also provides the app.all() method that works exactly the same as
the app.post() and app.get() methods. The only difference is that the callback function
for app.all() is called on every request for the specified path regardless of HTTP method.
Also, the app.all() method can accept the * character as a wildcard in the path. This is a great
feature for implementing request logging or other special functionality to handle requests. For
example:
4
FULLSTACK NOTES N.NAGAVENI
5
FULLSTACK NOTES N.NAGAVENI
6
FULLSTACK NOTES N.NAGAVENI
7
FULLSTACK NOTES N.NAGAVENI
8
FULLSTACK NOTES N.NAGAVENI
The route parameters in the content pane reads: Query URL: /find? Author=Brad&title=Node
Finding Book: Author: Brad Title: Node Regex URL: /book/12:15 Get Book: Chapter: 12
Page: 15 Para URL: /User/4983 Get User: 4983
Figure 18.1 Implementing route parameters using query strings, regex, and defined
parameters
Using Requests Objects
The route handlers are passed a Request object as the first parameter. The Request object
provides the data and metadata about the request, including the URL, headers, query string,
and much more. This allows you to handle the request appropriately in your code.
Table 18.2 lists some of the more commonly used properties available in the Request object.
9
FULLSTACK NOTES N.NAGAVENI
10
FULLSTACK NOTES N.NAGAVENI
The properties in the console window reads: URL: /user/4983? name=Brad Protocol: http IP:
127.0.0.1 Path: /user/4983 Host: localhost Method: GET Query: {"name":"Brad"} Fresh:
false Stale: true Secure: false UTF8: true Connection: keep-alive Headers: { "host":
"localhost", "connection": "keep-alive", "accept":
"text/html,application/xhtml+xml,application/: "user-agent": "Mozilla/5.0 (Windows NT 6.1;
WOW64) Appl. "accept-encoding": "gzip,deflate,sdch", "accept-language": "en-
US,en;q=0.8", "if-none-match": "\"-1050218291\"" }
Figure 18.2 Accessing properties of the Request object
11
FULLSTACK NOTES N.NAGAVENI
12
FULLSTACK NOTES N.NAGAVENI
the status(number) method where the number parameter is the HTTP response status defined
in the HTTP spec.
For example, the following lines set different statuses:
res.status(200); // OK
res.status(300); // Redirection
res.status(400); // Bad Request
res.status(401); // Unauthorized
res.status(403); // Forbidden
res.status(500); // Server Error
Sending Response
You already saw the send() method in action when sending simple responses in some earlier
examples in this chapter. The send() method can use one of the following formats, where
status is the HTTP status code and body is a String or Buffer object:
res.send(status, [body])
res.send([body])
If you specify a Buffer object, the Content-Type is automatically set to application/octet-
stream unless you explicitly set it to something else. For example:
res.set('Content-Type', 'text/html');
res.send(new Buffer('<html><body>HTML String</body></html>'));
The send() method can really handle all the responses necessary as long as you set the
appropriate headers and status for the response. Once the send() method completes, it sets the
value of the res.finished and res.headerSent properties. You can use these to verify the
response was sent as well as how much data was transferred. The following shows an
example value of the res.headerSent property:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html
Content-Length: 92
Date: Tue, 17 Dec 2013 18:52:23 GMT
Connection: keep-alive
Example: express_send.js: Sending status, headers, and response data using
the Response object
01 var express = require('express');
02 var url = require('url');
13
FULLSTACK NOTES N.NAGAVENI
14
FULLSTACK NOTES N.NAGAVENI
Console tab is selected with the following text in the content pane: Response Finished? True
Headers Sent: HTTP/1.1 200 OK X-Powered-BY: Express Content-Type: text.html Content-
Length: 92 Date: Tue, 17 Dec 2013 21:50:10 GMT Connection: keep-alive
Figure 18.3 The res.headerSent output after a response has been sent
Sending JSON Responses
A growing trend has been to use JSON data to transfer information from the server to the
client and then having the client dynamically populate the HTML elements on the page,
rather than the server building HTML documents or parts of HTML documents and sending
the HTML to the client. Express facilitates sending JSON by providing
the json() and jsonp() methods on the Response object. These methods use a similar syntax
as send() except that the body is a JSON stringifiable JavaScript object:
res.json(status, [object])
res.json([body])
res.jsonp(status, [object])
res.jsonp([object])
The JavaScript object is converted to a JSON string and sent back to the client. In the case
of jsonp(), the URL of the request object includes a ?callback=<method> parameter and then
the JSON string is wrapped in a function with the method name that can be called from the
browser client to support the JSONP design.
15
FULLSTACK NOTES N.NAGAVENI
Listing 18.5 implements both json() and jsonp() to illustrate sending JSON data back to the
server. Notice that in line 6 the json spaces application setting is set to 4, and in line 7 a basic
JavaScript object is passed into the json() call. On line 12 an error code is set in the response,
and the response object is a JSON object.
In lines 14–19 the jsonp() method is implemented. Notice that the jsonp callback name is set
to cb in line 15. That means that instead of passing ?callback=<function> in the URL, the
client needs to pass ?cb=<function> in the URL. Figure 18.4 shows the output to the browser
for each of these calls.
Listing 18.5 express_json.js: Sending JSON and JSONP data in the response from
Express
01 var express = require('express');
02 var url = require('url');
03 var app = express();
04 app.listen(80);
05 app.get('/json', function (req, res) {
06 app.set('json spaces', 4);
07 res.json({name:"Smithsonian", built:'1846', items:'137M',
08 centers: ['art', 'astrophysics', 'natural history',
09 'planetary', 'biology', 'space', 'zoo']});
10 });
11 app.get('/error', function (req, res) {
12 res.json(500, {status:false, message:"Internal Server Error"});
13 });
14 app.get('/jsonp', function (req, res) {
15 app.set('jsonp callback name', 'cb');
16 res.jsonp({name:"Smithsonian", built:'1846', items:'137M',
17 centers: ['art', 'astrophysics', 'natural history',
18 'planetary', 'biology', 'space', 'zoo']});
19 });
Sending Files
A great helper method in Express is the sendfile(filepath) method on the Response object.
The sendfile() method does everything that needs to be done to send files to the client in a
single function call. Specifically, the sendfile() method does the following:
Sets the Content-Type header to the type based on file extension
16
FULLSTACK NOTES N.NAGAVENI
The coding in the screen reads: { "name": "Smithsonian", "built": "1846", "items": "137M",
"centers": [ "art", "astrophysics", "natural history", "planetary", "biology", "space", "zoo" ] }
17
FULLSTACK NOTES N.NAGAVENI
The coding in the screen reads: { status: false, message: Internal Server Error }
18
FULLSTACK NOTES N.NAGAVENI
The coding in the screen reads: typeof handleJSNP === 'function' && handleJSONP ( {
"name": "Smithsonian", "built": "1846", "items": "137K", "centers": [ "art", "astrophysics",
"natural history", "planetary", "biology", "space", "zoo" ] });
Figure 18.4 Sending JSON and JSONP data to the browser
Listing 18.6 illustrates how easy it is to send the contents of a file using
the sendfile() command. Notice that a root path is specified in line 8, so only the filename is
required in line 6. Also notice that the callback function has code to handle the error. Figure
18.5 shows the image displayed in the browser.
Listing 18.6 express_send_file.js: Sending files in an HTTP request from Express
01 var express = require('express');
02 var url = require('url');
03 var app = express();
04 app.listen(80);
05 app.get('/image', function (req, res) {
06 res.sendfile('arch.jpg',
07 { maxAge: 1,//24*60*60*1000,
08 root: './views/'},
19
FULLSTACK NOTES N.NAGAVENI
09 function(err){
10 if (err){
11 console.log("Error");
12 } else {
13 console.log("Success");
14 }
15 });
16 });
20
FULLSTACK NOTES N.NAGAVENI
22
FULLSTACK NOTES N.NAGAVENI
Angular
Why Angular?
JavaScript is a powerful programming language that allows developers to use a web browser
as a full application platform.
Angular provides a great framework that makes it faster and easier to create client-side
JavaScript applications.
Developers use Angular because it provides a lot of the structure of web applications—such
as data binding, dependency injection, and HTTP communications.
Understanding Angular
• Angular is a JavaScript framework, which means it provides a number of APIs and
structure that helps you quickly and easily create complex client-side code.
• Angular does a great job at providing not only features but also a basic framework
and programming model to create client applications.
Modules
In general, Angular apps use a modular design. While not required, modules are highly
recommended because they allow you to separate your code into separate files.
This helps you keep your code files short and manageable while still allowing you to access
the functionality from each one.
Unlike how you use modules with TypeScript, with Angular you import external modules at
the top of a file and export the functionality you need at the bottom.
You do this by using the key terms import and export, with the following syntax:
23
FULLSTACK NOTES N.NAGAVENI
Structural: You use structural directives when you need to manipulate the DOM. Structural
directives allow you to create and destroy elements and components from a view.
Attribute: An attribute directive changes the appearance and behavior of HTML elements by
using HTML attributes.
Data Binding
One of the best features of Angular is the built-in data binding—the process of linking data
from a component with what is displayed in a web page. Angular provides a very clean
interface to link model data to elements in a web page.
When data is changed on a web page, the model is updated, and when data is changed in the
model, the web page is automatically updated. This way, the model is always the only source
for data represented to the user, and the view is just a projection of the model.
Dependency Injection
Dependency injection is a process in which a component defines dependencies on other
components.
When the code is initialized, the dependent component is made available for access within
the component. Angular applications make heavy use of dependency injection.
A common use for dependency injection is consuming services. For example, if you are
defining a component that requires access to a web server via HTTP requests, you can inject
the HTTP services into the component, and the functionality is available in the component
code.
In addition, one Angular component consumes the functionality of another via dependency.
Services
Services are the major workhorses in the Angular environment.
Services are singleton classes that provide functionality for a web app.
For example, a common task of web applications is to perform AJAX requests to a web
server.
Angular provides an HTTP service that houses all the functionality to access a web server.
24
FULLSTACK NOTES N.NAGAVENI
Separation of Responsibilities
An extremely important part of designing Angular applications is the separation of
responsibilities. The whole reason you choose a structured framework is to ensure that code
is well implemented, easy to follow, maintainable, and testable. Angular provides a very
structured framework to work from, but you still need to ensure that you implement Angular
in the appropriate manner.
• The view acts as the official presentation structure for the application. Indicate any
presentation logic as directives in the HTML template of the view.
• Implement any reusable tasks as services and add them to your modules by using
dependency injection.
• Ensure that the metadata reflects the current state of the model and is the single source
for data consumed by the view.
• Define controllers within the module namespace and not globally to ensure that your
application can be packaged easily and avoid overwhelming the global namespace.
25
FULLSTACK NOTES N.NAGAVENI
A watcher so that the transpiler knows when there has been a file change
Note
We recommend that you use Visual Studio Code (https://code.visualstudio.com/); it has good
TypeScript and Angular support built in, and is a lightweight editor with many available
extensions.
Fortunately, the Angular team has done most of the work for you here. All you need to do is
go to the Angular QuickStart website, which walks you through the process. The following
Angular QuickStart website takes you through the basics of Angular:
https://angular.io/docs/ts/latest/quickstart.html. This website explains the basics of Angular’s
command-line interface (CLI): https://angular.io/docs/ts/latest/cli-quickstart.html.
Note
We recommend that you use the CLI while learning Angular. The CLI generates all the
bootstrap and configuration files for you. It also includes a lightweight server for testing your
code.
26
FULLSTACK NOTES N.NAGAVENI
One of the most common purposes of the CLI is to generate content for applications. It
automates the process of creating and bootstrapping a new Angular application, letting you
get straight to the meat of the application.
From the command line, run the command ng new [application name] to create a new
Angular application. If you navigate to that newly created application, you have access to
many other useful commands. Table 21.1 lists some of the most important commands that the
CLI has to offer.
While an in-depth guide of everything the CLI has to offer is beyond the scope of this book,
it is worth learning how to use.
27
FULLSTACK NOTES N.NAGAVENI
Now that you understand the basics of the Angular CLI, you are ready to get started
implementing Angular code.
For this example, it is expected that you have started working through the Angular QuickStart
guide and understand the basics of the CLI. The first thing to do is to create a directory where
you can place your projects.
When you have your directory set up, the next step is to generate your first Angular
application.
Run the following command to create the application for this example:
ng new first
Next, run the following command to launch a server that will render the application:
ng serve
The following sections describe the important steps in implementing the Angular application
and the code involved in each step. Each of these steps is described in much more detail in
later chapters, so don't get bogged down in them here. What is important at this point is that
you understand the process of implementing the HTML, component, class, and bootstrap and
generally how they interact with each other.
Figure 21.1 shows the web application you are going to create. It shows a simple message
that has been printed out by an Angular component.
Figure 21.1 Implementing a basic Angular web application that uses a component to load an
HTML template to the view
28
FULLSTACK NOTES N.NAGAVENI
After the decorator is defined, lines 8–10 create the export class to make your component
available to the rest of the application as well as define variables and functions that are made
available to the component template.
providers: This is an array of injectable objects that are available in the injector of the
current module.
declarations: This is an array of directives, pipes, and/or components that belong in the
current module.
29
FULLSTACK NOTES N.NAGAVENI
imports: This is an array of directives, pipes, and/or components that will be available to
other templates within the current module.
exports: This is an array of directives, pipes, and/or modules that can be used within any
component that imports the current module.
entryComponents: This is an array of components that will be compiled and will have a
component factory created when the current module is defined.
bootstrap: This is an array of components that will be bootstrapped when the current
module is bootstrapped.
schemas: This is an array of elements and properties that aren’t directives or components.
id: This is a simple string that acts as a unique ID to identify this module.
As is often the case, it’s easiest to learn this by doing, so let’s get started using NgModule.
Navigate to the file named app.module.ts in your app folder. It looks like this:
30
FULLSTACK NOTES N.NAGAVENI
13 BrowserModule,
14 FormsModule,
15 HttpModule
16 ],
17 providers: [],
18 bootstrap: [Chap3Component]
19 })
20 export class AppModule { }
First, you import NgModule, BrowserModule, and any custom components, directives,
services, and so on that your app has. Second, you configure the @NgModule object to
bootstrap everything together. Notice that when the component is imported, the bootstrap
property has the component’s export class name. Finally, you export the class named
AppModule.
Navigate to the file named main.ts in your app folder, which looks like this:
31
FULLSTACK NOTES N.NAGAVENI
platformBrowserDynamic().bootstrapModule(AppModule);
platform is then assigned the result from the function platformBrowserDynamic. platform has
the method bootstrapModule(), which consumes the module. Notice that when you import
and bootstrap a component, the name you use is the same as the component’s export class.
Now open the command prompt, navigate to your root directory, and run the command ng
serve. This command compiles your code and opens a browser window. You may need to
point your browser to the local host and port. The command lets you know the URL to
navigate your browser to, as shown in the following example:
Listing 21.2 shows the Angular module that bootstraps the component. Lines 1–4 show the
Angular modules BrowserModule, NgModule, FormsModule, and HttpModule each getting
imported. Line 6 shows the Angular component Chap3Component getting imported. Lines 9–
11 show the component being declared. Lines 12–16 show the imports array which makes the
imported modules available to the application. Line 18 bootstraps the main component of the
application.
Note
This application doesn’t need the FormsModule or the HttpModule to run. However, they are
included to help show the syntax of importing extra modules into the application.
32
FULLSTACK NOTES N.NAGAVENI
Listing 21.3 shows the Angular component which has the selector message. This component
displays the message Hello World! in the browser.
Listing 21.1 first.html: A Simple Angular Template That Loads the First Component
01 <!doctype html>
02 <html>
03 <head>
04 <meta charset="utf-8">
05 <title>First</title>
06 <base href="/">
07
08 <meta name="viewport" content="width=device-width, initial-scale=1">
09 <link rel="icon" type="image/x-icon" href="favicon.ico">
10 </head>
11 <body>
12 <message>Loading...</message>
13 </body>
14 </html>
Listing 21.2 app.module.ts: An Angular Module that bootstraps the application
33
FULLSTACK NOTES N.NAGAVENI
10 Chap3Component
11 ],
12 imports: [
13 BrowserModule,
14 FormsModule,
15 HttpModule
16 ],
17 providers: [],
18 bootstrap: [Chap3Component]
19 })
20 export class AppModule { }
Listing 21.3 first.component.ts: An Angular Component
34
FULLSTACK NOTES N.NAGAVENI
This is the only time we show you the compiled JavaScript files in this book because these
are generated automatically for you when the application is compiled and run—and to help
keep the book more readable.
Listing 21.4 app.module.js: The JavaScript Version of the Angular Module that bootstraps the
application
01 "use strict";
02 var __decorate = (this && this.__decorate) ||
03 function (decorators, target, key, desc) {
04 var c = arguments.length, r = c < 3 ? target :
05 desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
06 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
07 r = Reflect.decorate(decorators, target, key, desc);
08 else for (var i = decorators.length - 1; i >= 0; i--)
09 if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r)
10 : d(target, key)) || r;
11 return c > 3 && r && Object.defineProperty(target, key, r), r;
12 };
13 exports.__esModule = true;
14 var platform_browser_1 = require("@angular/platform-browser");
15 var core_1 = require("@angular/core");
16 var forms_1 = require("@angular/forms");
17 var http_1 = require("@angular/http");
18 var app_component_1 = require("./app.component");
19 var AppModule = (function () {
20 function AppModule() {
21 }
35
FULLSTACK NOTES N.NAGAVENI
22 AppModule = __decorate([
23 core_1.NgModule({
24 declarations: [
25 app_component_1.Chap3Component
26 ],
27 imports: [
28 platform_browser_1.BrowserModule,
29 forms_1.FormsModule,
30 http_1.HttpModule
31 ],
32 providers: [],
33 bootstrap: [app_component_1.Chap3Component]
34 })
35 ], AppModule);
36 return AppModule;
37 }());
38 exports.AppModule = AppModule;
Listing 21.5 first.component.js: The JavaScript Version of the Angular Component File
01 "use strict";
02 var __decorate = (this && this.__decorate)
03 || function (decorators, target, key, desc) {
04 var c = arguments.length, r = c < 3
05 ? target : desc === null
06 ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
07 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
08 r = Reflect.decorate(decorators, target, key, desc);
09 else for (var i = decorators.length - 1; i >= 0; i--)
10 if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3
11 ? d(target, key, r) : d(target, key)) || r;
36
FULLSTACK NOTES N.NAGAVENI
Angular Components
Angular components are the building blocks you use to create Angular applications. Angular
components allow you to build self-contained UI elements for an application.
Components allow you to control how your application looks and functions through
TypeScript code and an HTML template.
Component Configuration
An Angular component consists of two main parts: the definition in the decorator section and
the class section, which defines the logic.
The decorator section is used to configure the component, including things like the selector
name and HTML template.
The class section enables you to give the component its logic, data, and event handlers, as
well as export it to be used in other TypeScript files.
37
FULLSTACK NOTES N.NAGAVENI
With these two sections you can create a basic component. The following example shows
what a component might look like:
Import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: '<p>My Component</p>'
})
Export class AppComponent{
Title = 'Chapter 1 Example';
}
To create a component, you import Component from Angular and apply it to a TypeScript
class that you can then use to control the look and functionality of the component.
Within the @Component decorator are several component configuration options you need to
understand. The following list includes some of the most important options available:
selector: This option allows you to define the HTML tag name used to add the component
to the application via HTML.
template: This option allows you to add inline HTML to define the look of the component.
This is for when there won’t be very much code to add, and it’s helpful for when you don’t
want extra files.
templateUrl: This option allows you to import an external template file rather than inline
HTML. This is helpful for separating a large amount of HTML code out of a component to
help with maintainability.
styles: This option allows you to add inline CSS to your component. Use it when only
minor style changes are needed.
stylesUrls: This option allows you to import an array of external CSS stylesheet(s). You
should use this rather than styles when importing external CSS files.
viewProviders: This is an array of dependency injection providers. It allows you to import
and use Angular services that provide application functionality such as HTTP
communications.
Defining a Selector
In a component, a selector tells Angular where to apply the component in HTML.
we apply Angular to a component to HTML by giving it a selector and then using the
selector name as a tag name in your HTML file.
This makes the functionality of the Angular component available in HTML.
The following is an example of a selector:
38
FULLSTACK NOTES N.NAGAVENI
@Component({
selector: 'angular-rules'
})
we can then add the selector to HTML files by using the following syntax:
<angular-rules></angular-rules>
Note
It’s important to note that when defining a selector name, there can’t be any white spaces. For
example, you can’t name a selector angular rules, but you can name it angular-
rules or angular_rules.
Building a Template
You use a template to define how an Angular component should look. Templates are written
in HTML, Angular allows for both inline templates and external template files.
@Component({
selector: 'my-app',
template: '<h1>Hello World!</h1>'
})
@Component({
selector: 'my-app',
template: `
<h1>Hello World!</h1>
`
})
@Component ({
selector: 'my-app',
template: '<p>hello world</p>',
styles: [`
P{
color: yellow;
font-size: 25px;
}
`]
39
FULLSTACK NOTES N.NAGAVENI
})
Note
You need to use the backquote key for a multiple-line stylesheet.
Using Inline CSS and HTML in Angular Applications
You’ve learned how to implement HTML and CSS in an Angular component. This section
builds an example based on that knowledge.
In this exercise you will see how Angular components use and include external templates and
stylesheets.
The purpose of this exercise is to illustrate how this use of templates allows for more
readable and manageable code.
shows the finished Angular component rendered.
intro.ts: A Simple Angular Template and Styling to Display a <span> Element
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <span>Hello my name is Brendan</span>
07 `,
08 styles:[`
09 span {
10 font-weight: bold;
11 border: 1px ridge blue;
12 padding: 5px;
13 }
14 `]
15 })
16 export class AppComponent {
17 title = 'Chapter 22 Intro';
18 }
40
FULLSTACK NOTES N.NAGAVENI
Figure 22.1 Implementing a basic Angular web application that loads an HTML template and
styles to the view
Using Constructors
Angular uses constructors to give its components default values. This section goes over how
to create and implement them.
Constructors go in the Component class. Their purpose is to set default values and initial
configuration of variables for that class so that when those variables are used within the
component, they are never uninitialized.
The following is an example of constructor syntax:
export class constructor {
name: string;
constructor(){
this.name = "Brendan";
}
}
shows the rendered Angular component.
constructor.component.ts: A Simple Component that Displays the Date
01 import {Component} from '@angular/core';
02
41
FULLSTACK NOTES N.NAGAVENI
03 @Component({
04 selector: 'simple-constructor',
05 template: `
06 <p>Hello today is {{today}}!</p>
07 `,
08 })
09 export class UsingAConstructor {
10 today: Date;
11 constructor() {
12 this.today = new Date();
13 }
14 }
Figure 22.2 Implementing a basic Angular web application that uses a constructor to define
default variables
Using External Templates
Another way to incorporate templates and stylesheets into Angular components is through a
separate file.
42
FULLSTACK NOTES N.NAGAVENI
Under your @Component decorator, you place the keyword templateUrl followed by the path
from the root of the application to your template HTML file. Here is an example.
@Component ({
selector: 'my-app',
templateUrl: "./view.example.html"
})
You use the keyword styleUrls to tell the component about external stylesheets. The
difference with the external stylesheets is that you pass in an array of one or more stylesheets.
The following example shows how to import external stylesheets:
@Component ({
selector: 'my-app',
templateUrl: "./view.example.html"
styleUrls: ["./styles1.css", "./styles2.css"]
})
Note
The styleUrls configuration option takes in an array of comma-separated strings.
Earlier in this chapter, in the “Building a Template” section, you learned how to implement
external HTML and CSS files into an Angular component. The example in this section builds
on that knowledge and walks you through an Angular application that incorporates external
HTML and CSS files.
Listing 22.3 shows an Angular component with the selector named external,
and templateUrl and styleUrls, which link the external files you need for this application.
Listing 22.4 shows an external template named externalTemplate.html. The component uses
this file to render the view on the browser.
Listing 22.5 shows an external stylesheet named external.css. The component applies this file
to the component template file.
Figure 22.3 shows the finished Angular component rendered.
Listing 22.3 external.component.ts: An Angular Component with External File
Dependencies
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 templateUrl: './app.component.html',
43
FULLSTACK NOTES N.NAGAVENI
06 styleUrls: ['./app.component.css']
07 })
08 export class AppComponent {
09 title = 'Chapter 22 Using External templates and styles';
10 }
Listing 22.4 externalTemplate.html: An HTML Template File for the Component to Pull In
and Use
01 <h1>Congratulations</h1>
02 <p>
03 You've successfully loaded an external html file.
04 <span>
05 If I'm red then You managed to get the styles in there as well
06 </span>
07 </p>
Listing 22.5 external.css: A CSS Stylesheet for the Component to Apply to Its Template
01 span{
02 color: red;
03 border: 2px solid red;
04 }
44
FULLSTACK NOTES N.NAGAVENI
Figure 22.3 Implementing a basic Angular web application that loads an external HTML
template and stylesheet to the view
Injecting Directives
The idea of Angular dependency injection is to define and dynamically inject a dependency
object into another object, which makes available all the functionality provided by the
dependency object.
Angular provides dependency injection through the use of providers and an injector service.
In Angular, to use dependency injection on another directive or component, you need to add
the directive’s or component’s class name to the declarations metadata in
the @NgModule decorator within the module for the application, which takes in an array of
directives imported into your application.
The following is the syntax of the declarations array.
...
declarations: [ OuterComponent, InnerComponent ],
...
Building a Nested Component with Dependency Injection
You’ve learned what dependency injection is and how to use it for components and
directives. This section shows you how to use what you’ve learned to create a nested
component. This section walks you through an Angular application that incorporates a
component that has a second component within it.
45
FULLSTACK NOTES N.NAGAVENI
Listing 22.6 shows the outer.component.ts file, which loads an external template and
stylesheet.
Listing 22.7 shows the outer.html template file that the outer.component.ts file loads. Notice
that the HTML tag nested is a custom HTML tag that you use to load the inner component.
You do this exactly the same way you load the outer component in the main HTML file.
Listing 22.8 shows the outer.css file that gives the outer component and its child components
default styles. These styles are inherited by the inner component.
Listing 22.9 shows the inner.component.ts file. This is the inner component that the outer
component has injected. Notice that the selector for this component, which was used to load
this directive within the outer component, is nested.
Figure 22.4 shows the completed application in the browser window.
Listing 22.6 outer.component.ts: The Outer Component for the Application
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 templateUrl: './app.component.html',
06 styleUrls: ['./app.component.css']
07 })
08 export class AppComponent {
09 title = 'Nested Example';
10 }
Listing 22.7 outer.html: An HTML Template for the Component to Apply the View
01 <div>
02 <h1>the below text is a nested component</h1>
03 <nested></nested>
04 </div>
Listing 22.8 outer.css: A CSS Stylesheet for the Outer Component to Apply to Its Template
01 div {
02 color: red;
03 border: 3px ridge red;
04 padding: 20px;
46
FULLSTACK NOTES N.NAGAVENI
05 }
06 nested {
07 font-size: 2em;
08 font-weight: bolder;
09 border: 3px solid blue;
10 }
Listing 22.9 inner.component.ts: The Nested Component
01 import {Component} from '@angular/core';
02 @Component({
03 selector: 'nested',
04 template: `
05 <span>Congratulations I'm a nested component</span>
06 `,
07 styles: [`
08 span{
09 color: #228b22;
10 }
11 `]
12 })
13 export class InnerComponent {}
47
FULLSTACK NOTES N.NAGAVENI
The URL reads localhost:4200, is present with a text in the content pane reading the
below text is a nested component. "Congratulations Im a nested component, is
highlighted.
Figure 22.4 Displaying nested components
Passing in Data with Dependency Injection
Dependency injection is a powerful tool that allows you to build a reusable directive to be
used within any application that imports that directive.
Sometimes data needs to be passed through the application to the directive that’s being
injected. This is made possible through Angular inputs.
In Angular, to input data to another directive or component, you need to import
the Input decorator from @angular/core. The following code shows the syntax:
import {Component, Input} from '@angular/core';
When the Input decorator has been imported, you can begin to define what data you would
like to have input into the directive. Start by defining @input(), which takes in a string as a
parameter. The HTML uses that string to pass in the data to the imported directive. Do this by
using the following syntax:
@Input('name') personName: string;
Creating an Angular Application that Uses Inputs
Now that you have learned how to use inputs with dependency injection, it’s time to get
started on an example. This section walks through an Angular application that passes data to a
directive from another directive.
48
FULLSTACK NOTES N.NAGAVENI
Listing 22.10 shows the person.component.ts file, which is the entry point for the application
that will pass data into the input.component.ts file.
Listing 22.11 shows the input.component.ts file. It is the component that will take in and
handle the inputs from an external directive.
Figure 22.5 shows the completed application in the browser window.
Listing 22.10 person.component.ts: A Component that Imports input.component and Passes
Data to It through the Selector
01 import { Component } from '@angular/core';
02 import {myInput} from './input.component';
03 @Component({
04 selector: 'app-root',
05 template: `
06 <myInput name="Brendan" occupation="Student/Author"></myInput>
07 <myInput name="Brad" occupation="Analyst/Author"></myInput>
08 <myInput name="Caleb" occupation="Student/Author"></myInput>
09 <myInput></myInput>
10 `
11 })
12 export class AppComponent {
13 title = 'Using Inputs in Angular';
14 }
Listing 22.11 input.component.ts: A Component that Takes Data through Its Selector to
Modify What Is Displayed via HTML
01 import {Component, Input} from '@angular/core';
02 @Component ({
03 selector: "myInput",
04 template: `
05 <div>
06 Name: {{personName}}
07 <br />
08 Job: {{occupation}}
09 </div>
49
FULLSTACK NOTES N.NAGAVENI
10 `,
11 styles: [`
12 div {
13 margin: 10px;
14 padding: 15px;
15 border: 3px solid grey;
16 }
17 `]
18 })
19 export class myInputs {
20 @Input('name') personName: string;
21 @Input('occupation') occupation: string;
22 constructor() {
23 this.personName = "John Doe";
24 this.occupation = "Anonymity"
25 }
26 }
50
FULLSTACK NOTES N.NAGAVENI
Expressions
• A great feature of Angular is the capability to add JavaScript-like expressions inside
an HTML template.
• Angular evaluates expressions and then can dynamically add the results to a web
page.
• Expressions are linked to a component, and you can have an expression that utilizes
values in the component, and its value can change as the model changes.
Using Expressions
Using expressions is the simplest way to represent data from a component in an Angular
view.
Expressions are encapsulated blocks of code inside brackets, like this:
{{expression}}
The Angular compiler compiles an expression into HTML elements so that the results of the
expression are displayed. For example, look at the following expressions:
{{1+5}}
{{'One' + 'Two'}}
Based on these expressions, the web page displays the following values:
6
OneTwo
Expressions are bound to the data model, which provides two huge benefits. First, you can
use the property names and functions that are defined in the component inside your
expressions.
Second, because the expressions are bound to the component, when data in the component
changes, so do the expressions. For example, say that a component contains the following
values:
name: string='Brad';
score: number=95;
You can directly reference the name and score values in the template expressions, as shown
here:
Name: {{name}}
Score: {{score}}
Adjusted: {{score+5}}
51
FULLSTACK NOTES N.NAGAVENI
52
FULLSTACK NOTES N.NAGAVENI
53
FULLSTACK NOTES N.NAGAVENI
Figure 23.1 Using Angular expressions that contain strings, numbers, and basic math
operations
Interacting with the Component Class in Expressions
Now let's take a look at how to interact with the Component class inside Angular expressions.
In the previous example, all the input for the expressions came from explicit strings or
numbers.
This section illustrates the true power of Angular expressions that come from interacting with
the model.
Listing 23.2 shows an Angular component file that applies Angular expressions that use
values from the Component class to render text to the screen as well as act as parameters to
functions. Note that the variable names in the Component class can be used directly in the
expressions. For example, the expression in line 9 creates a string based on the values of
the speed and vehicle variables.
Figure 23.2 shows the rendered web page, based on the expressions. Note that when the links
of the page are clicked, the resulting function calls adjust the Component class variables,
which change how the previously discussed expressions are rendered.
Listing 23.2 classExpressions.component.ts: An Angular Application that Uses Expressions to
Interact with Data from the Component Class
01 import { Component } from '@angular/core';
02
03 @Component({
54
FULLSTACK NOTES N.NAGAVENI
04 selector: 'app-root',
05 template: `
06 Directly accessing variables in the component:<br>
07 {{speed}} {{vehicle}}<hr>
08 Adding variables in the component:<br>
09 {{speed + ' ' + vehicle}}<hr>
10 Calling function in the component:<br>
11 {{lower(speed)}} {{upper('Jeep')}}<hr>
12 <a (click)="setValues('Fast', newVehicle)">
13 Click to change to Fast {{newVehicle}}</a><hr>
14 <a (click)="setValues(newSpeed, 'Rocket')">
15 Click to change to {{newSpeed}} Rocket</a><hr>
16 <a (click)="vehicle='Car'">
17 Click to change the vehicle to a Car</a><hr>
18 <a (click)="vehicle='Enhanced ' + vehicle">
19 Click to Enhance Vehicle</a><hr>
20 `,
21 styles:[`
22 a{color: blue; text-decoration: underline; cursor: pointer}
23 `]
24 })
25 export class AppComponent {
26 speed = 'Slow';
27 vehicle = 'Train';
28 newSpeed = 'Hypersonic';
29 newVehicle = 'Plane';
30 upper = function(str: any){
31 str = str.toUpperCase();
32 return str;
33 }
55
FULLSTACK NOTES N.NAGAVENI
56
FULLSTACK NOTES N.NAGAVENI
Figure 23.2 Using Angular expressions to represent and use Component class data in the
Angular view
57
FULLSTACK NOTES N.NAGAVENI
58
FULLSTACK NOTES N.NAGAVENI
Figure 23.3 Using Angular expressions that apply TypeScript array and Math operations to
interact with scope data
Using Pipes
A great feature of Angular is the capability to implement pipes. A pipe is a type of operator
that hooks into the expression parser and modifies the results of the expression for display in
a view—for example, to format time or currency values.
You implement pipes inside expressions, using the following syntax:
{{ expression | pipe}}
If you chain multiple pipes together, they are executed in the order in which you specify
them:
{{ expression | pipe | pipe }}
Some filters allow you to provide input in the form of function parameters. You add these
parameters by using the following syntax:
{{ expression | pipe:parameter1:parameter2 }}
59
FULLSTACK NOTES N.NAGAVENI
Angular provides several types of pipes that enable you to easily format strings, objects, and
arrays in component templates. Table 23.1 lists the built-in pipes provided with Angular.
Table 23.1 Pipes That Modify Expressions in Angular Component Templates
Filter Description
currency[ Formats a number as currency, based on the currencyCode value provided. If
no currencyCode value is provided, the default code for the locale is used.
:currencyCode?[
Here is an example:
:symbolDisplay?[
{{123.46 | currency:"USD" }}
:digits?]]]
Json Formats a TypeScript object into a JSON string. Here is an example:
{{ {'name':'Brad'} | json }}
slice:start:end Limits the data represented in the expression by the indexed amount. If the
expression is a string, it is limited in the number of characters. If the result of
the expression is an array, it is limited in the number of elements. Consider
these examples:
{{ "Fuzzy Wuzzy" | slice:1:9 }}
{{ ['a','b','c','d'] | slice:0:2 }}
Lowercase Outputs the result of the expression as lowercase.
Uppercase Outputs the result of the expression as uppercase.
number[:pre.post- Formats the number as text. If a pre parameter is specified, the number of
postEnd] whole numbers is limited to that size. If post-postEnd is specified, the
number of decimal places displayed is limited to that range or size. Consider
these examples:
{{ 123.4567 | number:1.2-3 }}
{{ 123.4567 | number:1.3 }}
date[:format] Formats a TypeScript date object, a timestamp, or an ISO 8601 date string,
using the format parameter. Here is an example:
{{1389323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
The format parameter uses the following date formatting characters:
yyyy: Four-digit year
yy: Two-digit year
MMMM: Month in year, January through December
MMM: Month in year, Jan through Dec
MM: Month in year, padded, 01 through 12
60
FULLSTACK NOTES N.NAGAVENI
61
FULLSTACK NOTES N.NAGAVENI
This section shows how the built-in Angular pipes handle the transformation of data in
Angular expressions. The purpose of this example is to show how pipes transform the data
provided.
Listing 23.4 shows the Angular component with a template that contains several examples of
built-in pipes wrapped in {{}} brackets. The Component class contains data for some of the
pipes to use.
Figure 23.4 shows the rendered application with the transformed data.
Listing 23.4 builtInPipes.component.ts: An Angular Component That Contains an Example of
Built-in Pipes
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 Uppercase: {{"Brendan" | uppercase }}<br>
07 Lowercase: {{"HELLO WORLD" | lowercase}}<br>
08 Date: {{ today | date:'yMMMMEEEEhmsz'}}<br>
09 Date: {{today | date:'mediumDate'}}<br>
10 Date: {{today | date: 'shortTime'}}<br>
11 Number: {{3.1415927 | number:'2.1-5'}}<br>
12 Number: {{28 | number:'2.3'}}<br>
13 Currency: {{125.257 | currency:'USD':true: '1.2-2'}}<br>
14 Currency: {{2158.925 | currency}}<br>
15 Json: {{jsonObject | json}}<br>
16 PercentPipe: {{.8888 | percent: '2.2'}}<br>
17 SlicePipe: {{"hello world" | slice:0:8}}<br>
18 SlicePipe: {{days | slice:1:6}}<br>
19 legen... {{wait | async}} {{dairy | async}}
20 `
21 })
22 export class AppComponent {
23 today = Date.now();
62
FULLSTACK NOTES N.NAGAVENI
Figure 23.4 Using Angular pipes that transform data within expressions
Building a Custom Pipe
Angular enables you to create your own custom pipes and then use them within expressions
and services as if they were built-in pipes.
63
FULLSTACK NOTES N.NAGAVENI
Angular provides the @pipe decorator to create a pipe and register it with the dependency
injector server.
The @pipe decorator takes in metadata, just as an Angular component does. syntax:
@Pipe({
name: 'example',
Pure: true
})
The pipe class works much the same as the Component class, in that it is where the logic of
the pipe resides. However, the logic needs to be within a Transform method, which tells the
pipe how to transform whatever is to the left of the pipe symbol (|). Review the following
example:
Export class customPipe{
Transform(parameter1:string, parameter2:number) : string {
myStr = "logic goes in here";
return myStr;
}
}
Creating a Custom Pipe
This section shows how to build a custom pipe that filters out select words from a string. The
purpose of this example is to show you how to create and apply a custom pipe that can
transform data.
Listing 23.5 custom.pipe.ts: An Angular Pipe That Replaces Certain Words in a String
01 import {Pipe} from '@angular/core';
02
03 @Pipe({name: 'censor'})
04 export class censorPipe{
05 transform(input:string, replacement:string) : string {
06 var cWords = ["bad", "rotten", "terrible"];
07 var out = input;
08 for(var i=0; i<cWords.length; i++){
09 out = out.replace(cWords[i], replacement);
10 }
64
FULLSTACK NOTES N.NAGAVENI
11 return out
12 }
13 }
Listing 23.6 customPipes.component.ts: An Angular Component That Imports and Uses
a Custom Pipe
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 {{phrase | censor:"*****"}}
07 `
08 })
09 export class AppComponent {
10 phrase:string="This bad phrase is rotten ";
11 }
Figure 23.5 Using a custom Angular pipe that transforms data in an expression
65
FULLSTACK NOTES N.NAGAVENI
Data Binding
• One of the best features of Angular is the built-in data binding.
• Data binding is the process of linking data from a component with what is displayed
in a web page. When data in the component changes, the UI rendered to the user is
automatically updated.
• Angular provides a very clean interface to link the model data to elements in a web
page.
Understanding Data Binding
Data binding means linking data in an application with the UI element that is rendered to the
user.
When data is changed in the model, the web page is automatically updated.
This way, the model is always the only source for data represented to the user, and the view
is just a projection of the model. The glue that puts the view and the model together is data
binding.
There are many ways in Angular to use data binding to make an application look and act in
different ways.
The following is a list of the types of data binding available with Angular that are discussed
in this chapter:
Interpolation: You can use double curly braces ({{}}) to get values directly from
the Component class.
Property binding: You can use this type of binding to set the property of an HTML
element.
Event binding: You can use this type of binding to handle user inputs.
Attribute binding: This type of binding allows the setting of attributes to an HTML
element.
Class binding: You can use this type of binding to set CSS class names to the element.
Style binding: You can use this type of binding to create inline CSS styles for the element.
Two-way binding with ngModel: You can use this type of binding with data entry forms to
receive and display data.
Interpolation
Interpolation involves using the {{}} double curly braces to evaluate a template expression.
This can be in a hard-coded form, or it can reference a property of the Component class.
The syntax for interpolation should look familiar from Chapter 23, “Expressions.” However,
you can also use interpolation to give an HTML tag property a value (for example,
the img tag). Here is an example of the syntax to do this:
<img src="{{imgUrl}}"/>
66
FULLSTACK NOTES N.NAGAVENI
Now let’s look at an example that shows some cool things you can do with interpolation
binding.
Listing 24.1 shows an Angular component. This component has a template that contains types
of interpolation and expressions wrapped in {{}} brackets. The Component class gives values
to be used within the {{}} brackets. (Be sure to change the imageSrc variable to the
appropriate image name.)
Figure 24.1 shows the rendered web page. As you can see, interpolation can use strings from
the Component class to populate the template.
Listing 24.1 interpolation.component.ts: Interpolation with Strings and a Function
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 {{str1 + ' ' + name}}
07 <br>
08 <img src="{{imageSrc}}" />
09 <br>
10 <p>{{str2 + getLikes(likes)}}</p>
11 `,
12 styles: [`
13 img{
14 width: 300px;
15 height: auto;
16 }
17 p{
18 font-size: 35px;
19 color: darkBlue;
20 }
21 `]
22 })
23 export class AppComponent {
67
FULLSTACK NOTES N.NAGAVENI
A browser tab labeled Interpolation, with URL localhost: 4200, is present with the
text in the content pane reading Hello my name is Brendan and below it, a Photo of Angel
landing is shown. The text below the photograph reads I like to hike, rappel, Jeep.
Figure 24.1 Using interpolation to combine strings, define an imageSrc URL, and run a
function
Property Binding
You use property binding when you need to set the property of an HTML element. You do
this by defining the value you want within the Component class. Then you bind that value to
the component template, using the following syntax:
68
FULLSTACK NOTES N.NAGAVENI
<img [src]="myValue">
Figure 24.2 shows the rendered web page. As you can see, interpolation can use strings
from the Component class to populate the template.
Listing 24.2 property.component.ts: Property Binding with Logic and the Application of a
Class Name
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <img [src]="myPic"/>
07 <br>
08 <button [disabled]="isEnabled">Click me</button><hr>
09 <button disabled="{!isEnabled}">Click me</button><br>
10 <p [ngClass]="className">This is cool stuff</p>
11 `,
12 styles: [`
13 img {
14 height: 100px;
15 width auto;
16 }
17 .myClass {
18 color: red;
19 font-size: 24px;
20 }
21 `]
22 })
23 export class AppComponent {
24 myPic: string = "../assets/images/sunset.JPG";
25 isEnabled: boolean = false;
26 className: string = "myClass";
69
FULLSTACK NOTES N.NAGAVENI
27 }
A browser tab labeled Property, with URL localhost: 4200, is shown. The top section
of the content pane shows a photograph of a lake with a Click me, button below it. The
second section of the content pane shows Click me, button with a text reading This is
cool stuff.
Figure 24.2 Using property binding to define an imageSrc URL, set a button to disabled
mode, and assign a class name
Attribute Binding
Attribute binding is similar to property binding but is tied to the HTML attribute rather than
the DOM property. You are not likely to use attribute binding very often, but it is important to
know what it is and how to use it. You will generally only use attribute binding on attributes
that do not have a corresponding DOM property (for example, aria, svg, and table
span attributes). You define an attribute binding by using the following syntax:
<div [attr.aria-label] = "labelName"></div>
Class Binding
You use class binding to bind CSS style tags to HTML elements. It assigns the class based on
the result of an expression being true or false. If the result is true, the class gets assigned. The
following is an example of the syntax:
<div [class.nameHere] = "true"></div>
<div [class.anotherName] = "false"></div>
70
FULLSTACK NOTES N.NAGAVENI
Figure 24.3 shows the rendered web page. As you can see, the class names take effect and
allow the CSS styles to change the HTML.
Listing 24.3 class.component.ts: Property Binding with Logic and the Application of a Class
Name
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <div [class]="myCustomClass"></div>
07 <span [class.redText]="isTrue">Hello my blue friend</span>
08 `,
09 styles: [`
10 .blueBox {
11 height: 150px;
12 width: 150px;
13 background-color: blue;
14 }
15 .redText{
16 color: red;
17 font-size: 24px;
18 }
19 `]
20 })
21 export class AppComponent {
22 myCustomClass: string = 'blueBox';
23 isTrue = true;
24 }
71
FULLSTACK NOTES N.NAGAVENI
Figure 24.3 An Angular application that applies class binding to add custom classes to HTML
elements
Style Binding
You use style binding to assign inline styles to an HTML element. Style binding works by
defining the CSS style property in the brackets, with the assignment expression in the
quotation marks. The syntax looks almost the same as for class binding but with style instead
of class as the prefix:
<p [style.styleProperty] = "assignment"></p>
<div [style.backgroundColor] = "'green'"></div>
Listing 24.4 style.component.ts: Style Binding to Change the Appearance of the HTML
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <span [style.border]="myBorder">Hey there</span>
07 <div [style.color]="twoColors ? 'blue' : 'forestgreen'">
08 what color am I
09 </div>
72
FULLSTACK NOTES N.NAGAVENI
Figure 24.4 The rendered web page with custom styles applied via a button that runs a
function to adjust the value of the twoColors variable
Event Binding
You use event binding to handle user inputs such as clicking, keystrokes, and mouse
movements. Angular event binding is similar to HTML event attributes; the major difference
is that the prefix “on” is removed from the binding, and instead the event is surrounded by
parentheses (()). For example, onkeyup in HTML looks like (keyup) in Angular.
A common purpose for event binding is to run functions from the component. The following
is the syntax for click event binding:
73
FULLSTACK NOTES N.NAGAVENI
<button (click)="myFunction()">button</button>
Listing 24.5 event.component.ts: Event Binding to Change the Image URL That Displays on
the Web Page
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <div (mousemove)="move($event)">
07 <img [src]="imageUrl"
08 (mouseenter)="mouseGoesIn()"
09 (mouseleave)="mouseLeft()"
10 (dblclick)="changeImg()" /><br>
11 double click the picture to change it<br>
12 The Mouse has {{mouse}}<hr>
13 <button (click)="changeImg()">Change Picture</button><hr>
14 <input (keyup)="onKeyup($event)"
15 (keydown)="onKeydown($event)"
16 (keypress)="keypress($event)"
17 (blur)="underTheScope($event)"
18 (focus)="underTheScope($event)">
19 {{view}}
20 <p>On key up: {{upValues}}</p>
21 <p>on key down: {{downValues}}</p>
22 <p>on key press: {{keypressValue}}</p>
23 <p (mousemove)="move($event)">
24 x coordinates: {{x}}
25 <br> y coordinates: {{y}}
26 </p>
27 </div>
28 `,
74
FULLSTACK NOTES N.NAGAVENI
29 styles: [`
30 img {
31 width: auto;
32 height: 300px;
33 }
34 `]
35 })
36 export class AppComponent {
37 counter = 0;
38 mouse: string;
39 upValues: string = '';
40 downValues: string = '';
41 keypressValue: string = "";
42 x: string = "";
43 y: string = '';
44 view: string = '';
45
46 mouseGoesIn = function(){
47 this.mouse = "entered";
48 };
49 mouseLeft = function(){
50 this.mouse = "left";
51 }
52 imageArray: string[] = [
53 "../assets/images/flower.jpg",
54 "../assets/images/lake.jpg", //extensions are case sensitive
55 "../assets/images/bison.jpg",
56 ]
57 imageUrl: string = this.imageArray[this.counter];
58 changeImg = function(){
75
FULLSTACK NOTES N.NAGAVENI
76
FULLSTACK NOTES N.NAGAVENI
89 console.log(event);
90 }
91 }
Figure 24.5 The initial result when the web page is loaded and the result from the event being
triggered
Two-Way Binding
Two-way binding allows for data to be easily displayed and updated simultaneously. This
makes it easy to reflect any changes the user makes to the DOM. Angular does this by
using ngModel to watch for changes and then update the value. This is the syntax:
<input [(ngModel)] = "myValue">
Figure 24.6 shows the rendered web page. It shows that the styles take effect and the CSS
styles change the HTML accordingly.
Listing 24.6 twoWay.component.ts: Different Methods to Implement Two-Way Data Binding
01 import { Component } from '@angular/core';
02 @Component({
03 selector: 'app-root',
04 template: `
05 <input [(ngModel)]="text"><br>
06 <input bindon-ngModel="text"><br>
07 <input [value]="text" (input)="text=$event.target.value">
77
FULLSTACK NOTES N.NAGAVENI
08 <h1>{{text}}</h1>
09 `
10 })
11 export class AppComponent {
12 text: string = "some text here";
13 }
Figure 24.6 An Angular application that shows multiple ways to accomplish two-way data
binding. The variable and the view are updated every time there is a change to the input field
Built-in Directives
One of the most powerful features Angular provides is directives. Directives extend the
behavior of HTML, enabling you to create custom HTML elements, attributes, and classes
with functionality specific to an application. Angular provides many built-in directives, which
provide the capability to interact with form elements, bind data in a component to the view,
and interact with browser events.
78
FULLSTACK NOTES N.NAGAVENI
Understanding Directives
Directives are a combination of Angular template markup and supporting TypeScript code.
Angular directive markups can be HTML attributes, element names, or CSS classes.
The TypeScript directive code defines the template data and behavior of the HTML elements.
The Angular compiler traverses the template DOM and compiles all directives. Then it links
the directives by combining a directive with a scope to produce a new live view. The live
view contains the DOM elements and functionality defined in the directive.
Attribute: A directive that manipulates the appearance and behavior of a DOM element
The following sections describe these three types of directives. You do not need to understand
all the directives right away. The following sections provide tables for reference. In addition,
the following sections and chapters provide sample code for using many of these directives.
Components Directives
Angular components are a form of structural directive that utilize a template. A component
creates a selector that is used as an HTML tag to dynamically add HTML, CSS, and Angular
logic to the DOM. Components are at the heart of Angular.
Structural Directives
Several directives dynamically update, create, and remove elements from the DOM. These
directives create the layout, look, and feel of an application. Table 25.1 lists these directives
and describes the behavior and usage of each.
79
FULLSTACK NOTES N.NAGAVENI
Directive Description
ngSwitch
This directive displays a template based on the value passed in it. As with ngIf, if the value
does not match the case, the element is not created. Here is an example:
<div [ngSwitch]="timeOfDay">
<span [ngSwitchCase]="'morning'">Morning</span>
<span [ngSwitchCase]="'afternoon'">Afternoon</span>
<span [ngSwitchDefault]="'daytime'">Evening</span>
The ngSwitch directive relies on two other directives to work: ngSwitchCase and
ngSwitchDefault. These directives are be explained below.
ngSwitchCase
80
FULLSTACK NOTES N.NAGAVENI
This directive evaluates the value it has stored against the value passed into ngSwitch and
determines whether the HTML template it is attached to should be created.
ngSwitchDefault
This directive creates the HTML template if all the above ngSwitchCase expressions evaluate
to false. This ensures that some HTML is generated no matter what.
• The above directives allow for dynamic manipulation of the DOM, based on what
data is passed to them.
• Structural directives dynamically manipulate the DOM by using expressions or
values. Two of the most common structural directives are ngIf and ngSwitch.
ngIf displays a section of HTML if a value or an expression returns true. ngIf uses the *
symbol to let Angular know it’s there. The following is an example of the syntax for ngIf:
ngFor is another example of a directive that uses the * symbol as a prefix to let Angular
know it’s there.
<div [ngSwitch]="time">
<span *ngSwitchCase="'night'">It's night time </span>
<span *ngSwitchDefault>It's day time </span>
The ngIf directive dynamically adds and removes HTML from the DOM.
ngSwitch does the same thing as ngIf, but it allows for more options, along with a default
option if all the cases return false.
81
FULLSTACK NOTES N.NAGAVENI
82
FULLSTACK NOTES N.NAGAVENI
Attribute Directives
Angular attribute directives modify how HTML elements look and behave.
They are injected straight into the HTML and dynamically modify how the user interacts
with an HTML segment.
83
FULLSTACK NOTES N.NAGAVENI
Attribute directives are so named because they often look like normal HTML attributes. An
example of an attribute directive that you’ve been using throughout the book is ngModel,
which modifies an element by changing the display value.
Below lists the attribute directives and describes the behavior and usage of each.
ngModel
This directive watches a variable for changes and then updates display values based on those
changes. Consider these examples:
<input [(ngModel)]="text"><br>
<h1>{{text}}</h1>
ngForm
This directive creates a form group and allows it to track the values and validation within that
form group. By using ngSubmit, you can pass the form data as an object to the submission
event. Here is an example:
84
FULLSTACK NOTES N.NAGAVENI
Custom Directives
As with many other features of Angular, you can extend functionality by creating your own
custom directives.
Custom directives allow you to extend the functionality of HTML by implementing the
behavior of elements yourself.
If you have code that needs to manipulate the DOM, it should be done inside a custom
directive.
You implement a custom directive by calling the @directive class, much the same way you
define a component. The @directive class metadata should include the selector of the
directive to be used in the HTML. The Directive export class is where the logic for the
directive will reside. For example, the following is a basic definition for a directive:
85
FULLSTACK NOTES N.NAGAVENI
86
FULLSTACK NOTES N.NAGAVENI
03 @Directive({
04 selector: '[zoom]'
05 })
06
07 export class ZoomDirective {
08 constructor(private el: ElementRef, private renderer: Renderer) { }
09
10 @HostListener('mouseenter') onMouseEnter() {
11 this.border('lime', 'solid', '5px');
12 }
13
14 @HostListener('mouseleave') onMouseLeave() {
15 this.border();
16 }
17 @HostListener('wheel', ['$event']) onWheel(event: any) {
18 event.preventDefault();
19 if(event.deltaY > 0){
20 this.changeSize(-25);
21 }
22 if(event.deltaY < 0){
23 this.changeSize(25);
24 }
25 }
26 private border(
27 color: string = null,
28 type: string = null,
29 width: string = null
30 ){
31 this.renderer.setElementStyle(
32 this.el.nativeElement, 'border-color', color);
87
FULLSTACK NOTES N.NAGAVENI
33 this.renderer.setElementStyle(
34 this.el.nativeElement, 'border-style', type);
35 this.renderer.setElementStyle(
36 this.el.nativeElement, 'border-width', width);
37 }
38 private changeSize(sizechange: any){
39 let height: any = this.el.nativeElement.offsetHeight;
40 let newHeight: any = height + sizechange;
41 this.renderer.setElementStyle(
42 this.el.nativeElement, 'height', newHeight + 'px');
43 }
44 }
Listing 26.3 app.component.html: An HTML File That Uses the Zoom Directive
01 <h1>
02 Attribute Directive
03 </h1>
04 <span *ngFor="let image of images">
05 <img zoom src="{{image}}" />
06 </span>
Listing 26.4 app.component.css: A CSS File that Sets the Image Height
01 img {
02 height: 200px;
03 }
88
FULLSTACK NOTES N.NAGAVENI
89
FULLSTACK NOTES N.NAGAVENI
03 @Component({
04 selector: 'app-root',
05 templateUrl: './app.component.html',
06 styleUrls: ['./app.component.css'],
07 })
08 export class AppComponent {
09
10 images: any = [
11 {
12 src: "../assets/images/angelsLanding.jpg",
13 title: "Angels Landing",
14 description: "A natural wonder in Zion National Park Utah, USA"
15 },
16 {
17 src: "../assets/images/pyramid.JPG",
18 title: "Tikal",
19 description: "Mayan Ruins, Tikal Guatemala"
20 },
21 {
22 src: "../assets/images/sunset.JPG"
23 },
24 ]
25 }
Listing 26.6 shows the HTML for the root component. The code creates several elements of
different types, such as image, div, and p, and applies the container directive to them.
Listing 26.6 app.component.html: HTML for the Root Component
01 <span *ngFor="let image of images" container title="{{image.title}}"
02 description="{{image.description}}">
03 <img src="{{image.src}}" />
04 </span>
05 <span container>
90
FULLSTACK NOTES N.NAGAVENI
91
FULLSTACK NOTES N.NAGAVENI
11 }
Listing 26.9 shows the HTML for the container directive. Lines 2 through 4 create the title
bar for the container. Lines 5 through 7 apply the content attribute directive. ng-content acts
as a placeholder and will be replaced with the template from the container component shown
in Listing 26.8. Lines 8 through 10 create the description bar for the container component.
Listing 26.9 container.component.html: HTML for the Container Component
01 <div class="sticky">
02 <div class="title" >
03 {{ title }}
04 </div>
05 <div class="content">
06 <ng-content></ng-content>
07 </div>
08 <div class="description">
09 {{ description }}
10 </div>
11 </div>
Listing 26.10 shows the CSS for the container component. This file sets the CSS to give the
container component borders, a title bar, and a description bar.
Listing 26.10 container.component.css: CSS for the Container Component
01 .title {
02 color: white;
03 background-color: dimgrey;
04 padding: 10px;
05 }
06 .content {
07 text-align: center;
08 margin: 0px;
09 }
10 .description {
11 color: red;
12 background-color: lightgray;
92
FULLSTACK NOTES N.NAGAVENI
13 margin-top: -4px;
14 padding: 10px;
15 }
16 .sticky {
17 display: inline-block;
18 padding: 0px;
19 margin: 15px;
20 border-left: dimgrey 3px solid;
21 border-right: dimgrey 3px solid;
22 }
The web page that results from Listings 26.5 through 26.10 is shown in Figure 26.2.
93
FULLSTACK NOTES N.NAGAVENI
• Angular provides several built-in services and also allows you to create your own
customized services.
A service provides a container for reusable functionality that is readily available to Angular
applications. Services are defined and registered with the dependency injection mechanism in
Angular. This allows you to inject services into modules, components, and other services.
Table 28.1 describes some of the most common built-in services to give you an idea of what
is available. The following sections cover the http and router services in more detail.
2. http
Provides a simple-to-use functionality to send HTTP requests to the web server or other
service
3. router
Provides navigation between views and between sections within views
4. forms
94
FULLSTACK NOTES N.NAGAVENI
Provides a service that allows for dynamic and reactive forms with simple form validation
Sending HTTP GET and PUT Requests with the http Service
• The http service enables you to directly interact with the web server from your
Angular code. The http service uses the browser's XMLHttpRequest object
underneath but from the context of the Angular framework.
• There are two ways to use the http service.
• The simplest is to use one of the following built-in shortcut methods that correspond
to standard HTTP requests:
delete(url, [options])
get(url, [options])
head(url, [options])
post(url, data, [options])
put(url, data, [options])
In these methods, the url parameter is the URL of the web request.
The optional options parameter is a JavaScript object that specifies the options to use when
implementing the request.
Table 28.2 lists some the properties you can set in the options parameter.
Table 28.2 Properties that Can Be Defined in the config Parameter for http Service Requests
Property Description
95
FULLSTACK NOTES N.NAGAVENI
Headers Headers to send with the request. You can specify an object
containing the header names to be sent as properties. If a
property in the object has a null value, the header is not sent.
withCredentials A Boolean that, when true, indicates that the withCredentials flag
on the XHR object is set.
responseType The type of response to expect, such as JSON or text.
Configuring the HTTP Request
You can specify a request, a URL, and data by sending the options parameter directly to the
http(options) method. For example, the following are exactly the same:
http.get('/myUrl');
http({method: 'GET', url:'/myUrl'});
Implementing the HTTP Response Callback Functions
When you call a request method by using the http object, you get back an Observable object,
which allows the data sent or received to/from the server to be continuously observed.
Observables have many operators that use the RxJS library to allow for the transformation
and use of the data. The following are some useful methods:
1. map: Applies a function to each value in the observable sequence. This allows you to
dynamically transform the output of the observable stream into custom data formats.
2. toPromise: Converts the observable into a Promise object, which has access to the
methods available on a promise. Promise objects provide syntax to handle
asynchronous operations.
96
FULLSTACK NOTES N.NAGAVENI
4. debounce: Specifies an interval at which the observable stream will emit values. Only
the value of the observable at the interval is emitted; interim values are not emitted.
The following is a simple example of a GET request that returns an observable with syntax to
add operators:
get(): Observable<any>{
http.get(url)
.map(response => response.JSON())
.catch(err => Rx.Observable.of('the error was: ${err}'));
}
Implementing a Simple JSON File and Using the http Service to Access It
The code in Listings 28.1 through 28.5 implements a simple mock web server in the form of
a JSON file and the Angular application that accesses it. Figure 28.1 shows the output. The
web server contains a simple JSON object with a list of users. The web application allows a
user to view the list of users. The example is very rudimentary to ensure that the code is easy
to follow; it incorporates a GET request as well as an error-handling example.
Listing 28.1 shows the JSON file that contains the JSON object. This file can be accessed
using an HTTP GET request, which allows http to grab the JSON object and return it to the
Angular application as an observable.
Listing 28.1 dummyDB.JSON: A JSON Object that Contains Data for Users
01 [
02 {
03 "userId": 1,
04 "userName": "brendan",
05 "userEmail": "[email protected]"
06 },
07 {
08 "userId": 2,
09 "userName": "brad",
10 "userEmail": "[email protected]"
97
FULLSTACK NOTES N.NAGAVENI
11 },
12 {
13 "userId": 3,
14 "userName": "caleb",
15 "userEmail": "[email protected]"
16 },
17 {
18 "userId": 4,
19 "userName": "john",
20 "userEmail": "[email protected]"
21 },
22 {
23 "userId": 5,
24 "userName": "doe",
25 "userEmail": "[email protected]"
26 }
27 ]
Listing 28.2 http.component.ts: A Component that Implements the HTTP Service for a GET
Request
98
FULLSTACK NOTES N.NAGAVENI
11 })
12 export class AppComponent {
13 users = [];
14
15 constructor(private http: Http){
16 http.get('../assets/dummyDB.JSON')
17 .toPromise()
18 .then((data) => {
19 this.users = data.JSON()
20 })
21 .catch((err) =>{
22 console.log(err);
23 })
24 }
25 }
Listing 28.3 implements an Angular module that imports HttpModule to allow the http
service to be used throughout the application. HttpModule is imported from @angular/http on
line 4 and then added to the imports array on line 15.
01 import { BrowserModule } from '@angular/platform-browser';
02 import { NgModule } from '@angular/core';
03 import { FormsModule } from '@angular/forms';
04 import { HttpModule } from '@angular/http';
05
06 import { AppComponent } from './app.component';
07
08 @NgModule({
09 declarations: [
10 AppComponent
11 ],
12 imports: [
13 BrowserModule,
99
FULLSTACK NOTES N.NAGAVENI
14 FormsModule,
15 HttpModule
16 ],
17 providers: [],
18 bootstrap: [AppComponent]
19 })
20 export class AppModule { }
Listing 28.4 implements an Angular template that uses ngFor to create a list of users to be
displayed in the application.
01 <h1>
02 Users
03 </h1>
04 <div class="user" *ngFor="let user of users">
05 <div><span>Id:</span> {{user.userId}}</div>
06 <div><span>Username:</span> {{user.userName}}</div>
07 <div><span>Email:</span> {{user.userEmail}}</div>
08 </div>
Listing 28.5 is a CSS file that styles the application so that each user is distinguishable from
the rest and easy to see.
01 span{
02 width: 75px;
03 text-align: right;
04 font-weight: bold;
05 display: inline-block;
06 }
100
FULLSTACK NOTES N.NAGAVENI
07 .user{
08 border: 2px ridge blue;
09 margin: 10px 0px;
10 padding: 5px;
11 }
Figure 28.1 Implementing the http service to allow Angular components to interact with a
web server
This service is intended for development purposes only and shouldn’t ever be used in a
production application.
Listing 28.6 data.service.ts: An Angular Mock Service that Returns a JSON Object Called
Users
101
FULLSTACK NOTES N.NAGAVENI
11 "id": 2,
12 "userName": "brad",
13 "email": "[email protected]"
14 },
15 {
16 "id": 3,
17 "userName": "caleb",
18 "email": "[email protected]"
19 }
20 ]
21 return {users};
22 }
23 }
102
FULLSTACK NOTES N.NAGAVENI
103
FULLSTACK NOTES N.NAGAVENI
45 if (!user.userName || !user.email){
46 return;
47 }
48 this.UserService.createUser(user)
49 .then(res => {
50 this.users.push(res);
51 })
52 }
53 }
Listing 28.8 user.service.ts: An Angular Service that Uses http to Send and Get Data
from a Server
104
FULLSTACK NOTES N.NAGAVENI
105
FULLSTACK NOTES N.NAGAVENI
10 <h1>
11 Users
12 </h1>
13 <div class="userCard" *ngFor="let user of users">
14 <div><span>Id:</span> {{user.id}}</div>
15 <div><span>Username:</span> {{user.userName}}</div>
16 <div><span>Email:</span> {{user.email}}</div>
17 <button class="delete"
18 (click)="deleteUser(user); $event.stopPropagation()">x</button>
19 </div>
Listing 28.10 is a CSS file that styles the application so that each user is distinguishable from
the rest and easy to see.
01 span{
02 width: 75px;
03 text-align: right;
04 font-weight: bold;
05 display: inline-block;
06 }
07 .userCard{
08 border: 2px ridge blue;
09 margin: 10px 0px;
10 padding: 5px;
11 }
12 .selected{
13 background-color: steelblue;
14 color: white;
15 }
106
FULLSTACK NOTES N.NAGAVENI
Figure 28.2 Implementing a simple mock server to create and delete items from a database
Implementing a Simple Mock Server and Using the http Service to Update Items on the
Server
107
FULLSTACK NOTES N.NAGAVENI
Listing 28.12 data.service.ts: An Angular Mock Service that Returns a JSON Object Called
Users
108
FULLSTACK NOTES N.NAGAVENI
109
FULLSTACK NOTES N.NAGAVENI
32 this.selectedUser = user;
33 }
34
35 updateUser(user){
36 this.selectedUser = null;
37 this.UserService.updateUser(user)
38 .then(() => this.getUsers());
39 }
40 }
Listing 28.14 user.service.ts: An Angular Service that Gets Users and Updates a User
110
FULLSTACK NOTES N.NAGAVENI
19 return this.http
20 .put(url, JSON.stringify(user))
21 .toPromise()
22 .then(() => user)
23 .catch(this.handleError)
24 }
25
26 private handleError(error: any): Promise<any> {
27 console.error('An error occurred', error);
28 return Promise.reject(error.message || error);
29 }
30
31 }
01 <h1>
02 Users
03 </h1>
04 <div class="userCard" *ngFor="let user of users"
05 (click)="selectUser(user)"
06 [class.selected]="user === selectedUser">
07 <div><span>Id:</span> {{user.id}}</div>
08 <div><span>Username:</span> {{user.userName}}</div>
09 <div><span>Email:</span> {{user.email}}</div>
10 </div>
11
12 <div *ngIf="selectedUser">
13 <label>user name:</label>
14 <input #updateName [ngModel]="selectedUser.userName"/>
111
FULLSTACK NOTES N.NAGAVENI
15
16 <label>user email:</label>
17 <input #updateEmail [ngModel]="selectedUser.email" />
18
19
20 <button (click)="updateUser(
21 {'id': selectedUser.id,
22 'userName': updateName.value,
23 'email': updateEmail.value});
24 ">
25 Save
26 </button>
27 </div>
Listing 28.16 update.component.CSS: A CSS File that Styles the Application
01 span{
02 width: 75px;
03 text-align: right;
04 font-weight: bold;
05 display: inline-block;
06 }
07 .userCard{
08 border: 2px ridge blue;
09 margin: 10px 0px;
10 padding: 5px;
11 cursor: pointer;
12 }
13 .userCard:hover{
14 background-color: lightblue;
112
FULLSTACK NOTES N.NAGAVENI
15 }
16 .selected{
17 background-color: steelblue;
18 color: white;
19 }
To set up an app for routing, you need to import the Routes and Router modules from
@angular/router. To help keep the application simple to maintain, router should get its own
module that can be imported into the main application module.
Defining routes for an application is as simple as making an array of objects, with each object
defining a specific route. The two required options for each of these routes are path and
component. The path option specifies the tree to follow to reach the component. The
component option defines which component will be loaded into the view. The following
examples show the syntax for defining a Routes array:
113
FULLSTACK NOTES N.NAGAVENI
},
{
Path: 'routeWithParams/:param1/:param2',
Component: myComponent
}
]
Many more parameters can be added to the route object. Table 28.3 shows a list of some of
them.
Table 28.3 Properties that Can Be Defined in the config Parameter for route Service Object
Property Description
outlet Specifies the name used for the RouterOutlet that renders the route
canLoad Allows you to protect specific modules from being loaded in the route
Resolve Specifies a resolver that pre-fetches data for the route before activation
114
FULLSTACK NOTES N.NAGAVENI
Children Allows for a nested routes array that contains route objects (Each of these
objects has the same options described in this table.)
Once the routes array is defined, it needs to be implemented into the router so that the router
service knows it exists and knows how to use it. This is done by using the forRoot method on
RouterModule. The result of this is included in the routing module’s imports array.
The syntax for this looks as follows:
imports: [RouterModule.forRoot(routes)]
Using routes in Angular
To use routes in Angular, the routing module needs to be included within the main app
module and included within the imports—the same as for built-in Angular modules. Once it
is included within the application module, the defined routes become available throughout the
application.
To be able to use router within a component, Router and ActivatedRoute need to be imported
from @angular/router. Once they are imported, they need to be implemented via the
constructor. The following code shows the syntax:
Constructor(
private route: ActivatedRoute,
private router: Router
){}
There are two ways to navigate between routes. The first way is from HTML directly, using
the Angular directive routerLink, which has the following syntax:
<a routerLink="/myRoute">
115
FULLSTACK NOTES N.NAGAVENI
The second way to navigate between routes is from the component class, using the following
syntax:
myFunction(){
this.router.navigate(['myRoute'])
}
When the router is all wired up and ready to be used, the last step is to make sure the routes
get displayed on the application. You do this by using the Angular HTML tag router-outlet. It
is important to note that the component that uses router-outlet will be outside the router, and
anything besides router-outlet will always display, no matter what route is currently being
shown. You can implement router-outlet by using the following syntax:
<router-outlet></router-outlet>
Implementing a Simple Router
Listing 28.17 app.module.ts: An Angular Module that Imports the Router Module File
116
FULLSTACK NOTES N.NAGAVENI
15 HomeComponent
16 ],
17 imports: [
18 BrowserModule,
19 FormsModule,
20 HttpModule,
21 AppRoutingModule
22 ],
23 providers: [],
24 bootstrap: [AppComponent]
25 })
26 export class AppModule { }
Listing 28.18 shows the Router module, which defines the routes for the application. The
Router module imports Routes and RouterModule to enable routing within the application.
The Router module also imports any components that will be used as routes. Lines 5 through
14 define the routes array, which contains the route definitions for the application. Lines 6
through 9 define the home route that the application will default to because the path is set to
an empty string. The home route uses HomeComponent as the component that controls the
view. Lines 10 through 13 define a second route object that will be displayed when the path is
set to route2. This route uses Route2Component.
Listing 28.18 app-routing.module.ts: An Angular Module that Defines the routes for This
Application
117
FULLSTACK NOTES N.NAGAVENI
10 {
11 path: 'route2',
12 component: Route2Component
13 }
14 ];
15
16 @NgModule({
17 imports: [RouterModule.forRoot(routes)],
18 exports: [RouterModule]
19 })
20 export class AppRoutingModule { }
Listing 28.19 shows the root component for the application. This component has a simple
template that outputs router-outlet for router to display its routes.
Listing 28.19 app.component.ts: An Angular Component that Defines the Router Outlet
118
FULLSTACK NOTES N.NAGAVENI
01 <p>
02 route 2 works!
03 </p>
04 <a routerLink="/">Route 1</a>
Listing 28.23 shows the barebones route2 component file. Its main purpose is to load the
template file and make it available to the router.
119
FULLSTACK NOTES N.NAGAVENI
03 @Component({
04 selector: 'app-route2',
05 templateUrl: './route2.component.html'
06 })
07 export class Route2Component {}
120
FULLSTACK NOTES N.NAGAVENI
19 skipLocationChange: true
20 }
21 );
22 }
23 }
Listing 28.37 shows the root component app.component.ts. This file has a template that
declares router-outlet to display the views from the router.
121
FULLSTACK NOTES N.NAGAVENI
13 ){ }
14 gotoPage2(){
15 this.router.navigate(
16 ['/page2', this.text],
17 {
18 relativeTo: this.route,
19 skipLocationChange: true
20 }
21 );
22 }
23 }
Listing 28.39 page1.component.html: An HTML Template that Provides an Input Field to
Give a Value to Router Parameters
01 <span>
02 Enter Text to Pass As Params:
03 </span>
04 <input type=text [(ngModel)]="text" />
05 <button [disabled]="!text" (click)="gotoPage2()">Page 2</button>
122
FULLSTACK NOTES N.NAGAVENI
10 constructor(
11 private route: ActivatedRoute,
12 private router: Router
13 ) { }
14 ngOnInit() {
15 this.route.params
16 .subscribe(text => this.text = text.params);
17 }
18
19 goBack(){
20 this.router.navigate(['/page1']);
21 }
22 }
123