0% found this document useful (0 votes)
25 views123 pages

FullStack UNIT 4

The document provides an overview of using the Express framework in Node.js for web application development. It covers how to configure an Express server, define routes, handle HTTP requests, and implement route parameters. Additionally, it explains the Request object and its properties for managing incoming requests effectively.

Uploaded by

caspianlocke
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views123 pages

FullStack UNIT 4

The document provides an overview of using the Express framework in Node.js for web application development. It covers how to configure an Express server, define routes, handle HTTP requests, and implement route parameters. Additionally, it explains the Request object and its properties for managing incoming requests effectively.

Uploaded by

caspianlocke
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 123

FULLSTACK NOTES N.

NAGAVENI

UNIT-IV
Express and Angular

Express is a backend node.js Framework which is used to develop web applications


Express also extends the functionality of the http module to make it easy for you to handle
server routes, responses, cookies, and statuses of HTTP requests.
This chapter gets you started implementing Express as the webserver for your Node.js
applications.
You learn how to configure the Express server, design routes, and use
the Request and Response objects to send and receive HTTP requests.
You also get a look at how to implement template engines in Express.
Getting Started with Express
It is simple to start using Express in your Node.js projects. All you need to do is add
the express module using the following command from the root of your project:
npm install express
You can also add express to your package.json module to ensure that express is installed
when you deploy your application.
Once you have installed express, you need to create an instance of the express class to act as
the HTTP server for your Node.js application. The following lines of code import
the express module and create an instance of express that you can use:
var express = require('express');
var app = express();
Configuring Express Settings
Express provides several application settings that control the behavior of the Express server.
These settings define the environment as well as how Express handles JSON parsing, routing,
and views. Table 18.1 lists the different settings that can be defined on an express object.
The express object provides the set(setting,
value) and enable(setting) and disable(setting) methods to set the value of the application
settings. For example, the following lines of code enable the trust proxy setting and set
the view engine to pug:
app.enable('trust proxy');
app.disable('strict routing');
app.set('view engine', 'pug');
To get the value of a setting, you can use the get(setting), enabled(setting),
and disabled(setting) methods. For example:

1
FULLSTACK NOTES N.NAGAVENI

app.enabled('trust proxy'); \\true


app.disabled('strict routing'); \\true
app.get('view engine'); \\pug
Table 18.1 Express application settings
Setting Description
Env Defines the environment mode string, such as development, testing,
and production. The default is the value of process.env.NODE_ENV.
trust proxy Enables/disables reverse proxy support. The default is disabled.
jsonp callback Defines the default callback name of JSONP requests. The default is ?callback=.
name
json replacer Defines the JSON replacer callback function. The default is null.
json spaces Specifies the number of spaces to use when formatting JSON response. The
default is 2 in development, 0 in production.
case sensitive Enables/disables case sensitivity. For example, /home is not the same as /Home.
routing The default is disabled.
strict routing Enables/disables strict routing. For example, /home is not the same as /home/. The
default is disabled.
view cache Enables/disables view template compilation caching, which keeps the cached
version of a compiled template. The default is enabled.
view engine Specifies the default template engine extension that is used when rendering
templates if a file extension is omitted from the view.
Views Specifies the path for the template engine to look for view templates. The default
is ./views.
Starting the Express Server
To begin implementing Express as the HTTP server for your Node.js application, you need to
create an instance and begin listening on a port. The following three lines of code start a
rudimentary Express server listening on port 8080:
var express = require('express');
var app = express();
app.listen(8080);
The app.listen(port) call binds the underlying HTTP connection to the port and begins
listening on it. The underlying HTTP connection is the same connection produced using
the listen() method on a Server object created using the http library discussed earlier in this
book.

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

app.all('*', function(req, res){


// global handler for all paths
});
app.all('/user/*', function(req, res){
// global handler for /user path
});
Applying Parameters in Routes
To reduce the number of routes, you can implement parameters within the URL.
Parameters allow you to use the same route for similar requests by providing unique values
for different requests that define how your application handles the request and builds the
response.
For example, you would never have a separate route for every user or product in your system.
Instead you would pass in a user ID or product ID as a parameter to one route, and the server
code would use that ID to determine which user or product to use. There are four main
methods for implementing parameters in a route:
Query string: Uses the standard ?key=value&key=value... HTTP query string after the
path in the URL. This is the most common method for implementing parameters, but the
URLs can become long and convoluted.
POST params: When implementing a web form or other POST request, you can pass
parameters in the body of the request.
regex: Defines a regular expression as the path portion of the route. Express uses the regex
to parse the path of the URL and store matching expressions as an array of parameters.
Defined parameter: Defines a parameter by name using :<param_name> in the path
portion of the route. Express automatically assigns that parameter a name when parsing the
path.
The following sections discuss these methods with the exception of POST params, which is
covered in the next chapter.
Applying Route Parameters Using Query Strings
The simplest method to add parameters to a route is to pass them using the normal HTTP
query string format of ?key=value&key=value... Then you can use the url.parse() method
discussed earlier in the book to parse the url attribute of the Request object to get the
parameters.
The following code implements a basic GET route
to /find?author=<author>&title=<title> that accepts author and title parameters. To actually
get the value of author and title, the url.parse() method is used to build a query object:
app.get('/find', function(req, res){

5
FULLSTACK NOTES N.NAGAVENI

var url_parts = url.parse(req.url, true);


var query = url_parts.query;
res.send('Finding Book: Author: ' + query.author +
' Title: ' + query.title);
});
For example, consider the following URL:
/find?author=Brad&title=Node
The res.send() method returns:
Finding Book: Author: Brad Title: Node
Applying Route Parameters Using Regex
One way to implement parameters in routes is to use a regex expression to match patterns.
This allows you to implement patterns that do not follow a standard / formatting for the path.
The following code implements a regex parser to generate route parameters for GET requests
at the URL /book/<chapter>:<page> path. Notice that the values of the parameters are not
named; instead, req.params is an array of matching items in the URL path.
app.get(/^\/book\/(\w+)\:(\w+)?$/, function(req, res){
res.send('Get Book: Chapter: ' + req.params[0] +
' Page: ' + req.params[1]);
});
For example, consider the following URL:
/book/12:15
The res.send() method returns
Get Book: Chapter: 12 Page: 15
Applying Route Parameters Using Defined Parameters
If your data is more structured, a defined parameter is a better method to use than regex.
Using a defined parameter allows you to define your parameters by name within the route
path.
You define parameters in the path of the route using :<param_name>.
When using defined parameters, req.param is a function instead of an array, where
calling req.param(param_name) returns the value of the parameter.
The following code implements a basic :userid parameter expecting a URL with
a /user/<user_id> format:

6
FULLSTACK NOTES N.NAGAVENI

app.get('/user/:userid', function (req, res) {


res.send("Get User: " + req.param("userid"));
});
For example, consider the following URL:
/user/4983
The res.send() method returns
Get User: 4983
Applying Callback Functions for Defined Parameters
A major advantage of using defined parameters is that you can specify callback functions that
are executed if the defined parameter is found in a URL.
When parsing the URL, if Express finds a parameter that has a callback registered, it calls the
parameter’s callback function before calling the route handler.
You can register more than one callback function for a route.
To register a callback function, you use the app.param() method.
The app.param() method accepts the defined parameter as the first argument, and then a
callback function that receives the Request, Response, next, and value parameters.
app.param(param, function(req, res, next, value){} );
The Request and Response objects are the same as are passed to the route callback.
The next parameter is a callback function for the next app.param() callback registered, if any.
You must call next() somewhere in your callback function or the callback chain will be
broken. The value parameter is the value of the parameter parsed from the URL path.
For example, the following code logs every request received that has the userid parameter
specified in the route. Notice that next() is called before leaving the callback function:
app.param('userid', function(req, res, next, value){
console.log("Request with userid: " + value);
next();
});
To see how the preceding code works, consider the following URL:
/user/4983
The userid of 4983 is parsed from the URL and the consol.log() statement displays
Request with userid: 4983

7
FULLSTACK NOTES N.NAGAVENI

Applying Route Parameters Example


To clarify the example, implements query strings, regex, and defined parameters to Express
routes.
The POST method is covered in the next chapter.
Example:express_routes.js: Implementing route parameters in Express
01 var express = require('express');
02 var url = require('url');
03 var app = express();
04 app.listen(80);
05 app.get('/', function (req, res) {
06 res.send("Get Index");
07 });
08 app.get('/find', function(req, res){
09 var url_parts = url.parse(req.url, true);
10 var query = url_parts.query;
11 var response = 'Finding Book: Author: ' + query.author +
12 ' Title: ' + query.title;
13 console.log('\nQuery URL: ' + req.originalUrl);
14 console.log(response);
15 res.send(response);
16 });
17 app.get(/^\/book\/(\w+)\:(\w+)?$/, function(req, res){
18 var response = 'Get Book: Chapter: ' + req.params[0] +
19 ' Page: ' + req.params[1];
20 console.log('\nRegex URL: ' + req.originalUrl);
21 console.log(response);
22 res.send(response);
23 });
24 app.get('/user/:userid', function (req, res) {
25 var response = 'Get User: ' + req.param('userid');

8
FULLSTACK NOTES N.NAGAVENI

26 console.log('\nParam URL: ' + req.originalUrl);


27 console.log(response);
28 res.send(response);
29 });
30 app.param('userid', function(req, res, next, value){
31 console.log("\nRequest received with userid: " + value);
32 next();
33 });

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

Table 18.2 Properties and methods of the HTTP Request object


Setting Description
originalUrl The original URL string of the request.
Protocol The protocol string, for example, http or https.
Ip IP address of the request.
Path Path portion of the request URL.
Hostname Hostname of the request.
Method HTTP method. GET, POST, etc.
Query Query string portion of the request URL.
Fresh A Boolean that is true when last-modified matches the current.
Stale A Boolean that is false when last-modified matches.
Secure A Boolean that is true when a TLS connection is established.
acceptsCharset(charset) Returns true if the character set specified by charset is supported.
get(header) Returns the value of the header.
The below example illustrates accessing the various parts of the Request object. The
output shows the actual values associated with a GET request.
Example: express_request.js: Accessing properties of the Request object in Express
01 var express = require('express');
02 var app = express();
03 app.listen(80);
04 app.get('/user/:userid', function (req, res) {
05 console.log("URL:\t " + req.originalUrl);
06 console.log("Protocol: " + req.protocol);
07 console.log("IP:\t " + req.ip);
08 console.log("Path:\t " + req.path);
09 console.log("Host:\t " + req.host);
10 console.log("Method:\t " + req.method);
11 console.log("Query:\t " + JSON.stringify(req.query));
12 console.log("Fresh:\t " + req.fresh);
13 console.log("Stale:\t " + req.stale);
14 console.log("Secure:\t " + req.secure);

10
FULLSTACK NOTES N.NAGAVENI

15 console.log("UTF8:\t " + req.acceptsCharset('utf8'));


16 console.log("Connection: " + req.get('connection'));
17 console.log("Headers: " + JSON.stringify(req.headers,null,2));
18 res.send("User Request");
19 });

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

Using Response Objects


The Response object passed to the route handler provides the necessary functionality to build
and send a proper HTTP response.
The following sections discuss using the Response object to set headers, set the status, and
send data back to the client.
Setting Headers
An important part of formulating a proper HTTP response is to set the headers. For example,
setting the Content-Type header determines how the browser handles the response.
The Response object provides several helper methods to get and set the header values that are
sent with the HTTP response.
The most commonly used methods are get(header) and set(header, value), which gets and sets
any header value. For example, the following code first gets the Content-Type header and
then sets it:
var oldType = res.get('Content-Type');
res.set('Content-Type', 'text/plain');
Table 18.3 describes the helper methods to get and set header values.
Table 18.3 Methods to get and set header values on the Response object
Setting Description
get(header) Returns the value of the header specified.
set(header, value) Sets the value of the header.
set(headerObj) Accepts an object that contains multiple 'header':'value' properties. Each of
the headers in the headerObj is set in the Response object.
location(path) Sets the location header to the path specified. The path can be a URL path
such as /login, a full URL such as http://server.net/, a relative path such
as ../users, or a browser action such as back.
type(type_string) Sets the Content-Type header based on the type_string parameter.
The type_string parameter can be a normal content type such
as application/json, a partial type such as png, or it can be a file extension
such as .html.
attachment([filepath])Sets the Content-Disposition header to attachment, and if a filepath is
specified the Content-Type header is set based on the file extension.
Setting the Status
You also need to set the HTTP status for the response if it is something other than 200. It is
important to send the correct status response so that the browser or other applications can
handle the HTTP response correctly. To set the status response, use

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

03 var app = express();


04 app.listen(80);
05 app.get('/', function (req, res) {
06 var response = '<html><head><title>Simple Send</title></head>' +
07 '<body><h1>Hello from Express</h1></body></html>';
08 res.status(200);
09 res.set({
10 'Content-Type': 'text/html',
11 'Content-Length': response.length
12 });
13 res.send(response);
14 console.log('Response Finished? ' + res.finished);
15 console.log('\nHeaders Sent: ');
16 console.log(res.headerSent);
17 });
18 app.get('/error', function (req, res) {
19 res.status(400);
20 res.send("This is a bad request.");
21 });

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

Sets other appropriate headers such as Content-Length


Sets the status of the response
Sends the contents of the file to the client using the connection inside the Response object
The sendfile() method uses the following syntax:
res.sendfile(path, [options], [callback])
The path should point to the file that you want to send to the client.
The options parameter is an object that contains a maxAge property that defines the
maximum age for the content and a root property that is a root path to support relative paths
in the path parameter.
The callback function is called when the file transfer is complete and should accept
an error object as the only parameter.

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 });

Figure 18.5 Image file sent in an HTTP response to the client

20
FULLSTACK NOTES N.NAGAVENI

Sending a Download Response


Express also includes a res.download() method that works similarly to
the res.sendfile() method with only a few differences. The res.download() method sends the
file in the HTTP response as an attachment, which means the Content-Disposition header will
be set. The res.download() method uses the following syntax:
res.download(path, [filename], [callback])
The path points to the file to send to the client. The filename parameter can specify a different
filename that should be sent in the Content-Disposition header. The callback function is
executed once the file download has completed.
Redirecting the Response
A common need when implementing a webserver is the ability to redirect a request from the
client to a different location on the same server or on a completely different server.
The res.redirect(path) method handles redirection of the request to a new location.
Listing 18.7 illustrates the various redirection addressing that you can use. In line 6 a redirect
is done to a completely new domain address. In line 9 a redirect is made to a different path on
the same server, and in line 15 a redirect is made to a relative path on the same server.
Listing 18.7 express_redirect.js: Redirecting requests on an Express server
01 var express = require('express');
02 var url = require('url');
03 var app = express();
04 app.listen(80);
05 app.get('/google', function (req, res) {
06 res.redirect('http://google.com');
07 });
08 app.get('/first', function (req, res) {
09 res.redirect('/second');
10 });
11 app.get('/second', function (req, res) {
12 res.send("Response from Second");
13 });
14 app.get('/level/A', function (req, res) {
15 res.redirect("../B");
16 });
17 app.get('/level/B', function (req, res) {
21
FULLSTACK NOTES N.NAGAVENI

18 res.send("Response from Level B");


19 });

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:

Import {Component} from 'angular2/core';


Export class App{}

Features/Importance of the Angular:


Directives
Directives are JavaScript classes with metadata that defines the structure and behavior.
Directives provide the majority of UI functionality for Angular applications. There are three
major types of directives:
Components:
A component directive is a directive that incorporates an HTML template with JavaScript
functionality to create a self-contained UI element that can be added to an Angular
application as a custom HTML element. Components are likely to be the directives you use
the most in Angular.

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

The service functionality is completely independent of context or state, so it can be easily


consumed from the components of an application. Angular provides a lot of built-in service
components for basic uses, such as HTTP requests, logging, parsing, and animation. You can
also create your own services and reuse them throughout your code.

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 following are a few rules to follow when implementing Angular:

• The view acts as the official presentation structure for the application. Indicate any
presentation logic as directives in the HTML template of the view.

• If you need to perform any DOM manipulation, do it in a built-in or custom directive


JavaScript code—and nowhere else.

• 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.

Adding Angular to Your Environment


To get started with Angular, you need to set up a few things first to get it ready to use. Here’s
what you need:

Angular libraries to make Angular applications

25
FULLSTACK NOTES N.NAGAVENI

A web server to serve the files to the browser

A transpiler to convert your TypeScript code back to JavaScript

A watcher so that the transpiler knows when there has been a file change

An editor in which to write your code

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.

Using the Angular CLI


Angular provides a powerful CLI that makes building out Angular applications a much more
streamlined process. By using the CLI, you will quickly be able to generate new Angular
applications, components, directives, pipes, and services. The following sections go over
some of the most important tools available through the CLI.

Generating Content with the CLI

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.

Table 21.1 Angular CLI Command Options

Command Alias Purpose

ng new Creates a new Angular application


ng serve Builds and runs the angular application for
testing

ng eject Makes the webpack config files available to be


edited

ng generate component [name] ng g c [name] Creates a new


component

ng generate directive [name] ng g d [name] Creates a new directive

ng generate module [name] ng g m [name] Creates a module

ng generate pipe [name] ng g p [name] Creates a pipe

ng generate service [name] ng g s [name] Creates a service

ng generate enum [name] ng g e [name] Creates an enumeration

ng generate guard [name] ng g g [name] Creates a guard

ng generate interface [name] ng g i [name] Creates an interface

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.

Creating a Basic Angular Application

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

Creating Your First Angular App


Now that you’ve seen how Angular works, let’s get into a practical example. This example
doesn’t change much that was generated by the CLI, but it will familiarize you with the
different pieces of an Angular application.

To get started, navigate to the file src/app/app.component.ts in your application directory. It


looks like this:

28
FULLSTACK NOTES N.NAGAVENI

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


02 @Component({
03 selector: 'message',
04 template: `
05 <h1>Hello World!</h1>
06 `,
07 })
08 export class Chap3Component{
09 title = 'My First Angular App';
10 }
Notice that line l imports the component module. Then the component decorator is defined
and given a selector and a template. The selector is the name given to the component, and the
template is the HTML that the component will generate. For this example, change the
template and selector to match the ones on lines 3–6 and change the title variable as shown
on line 9.

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.

Understanding and Using NgModule


Now that you’ve created your component, you need some way to tell the rest of your app
about it. You do this by importing NgModule from Angular. NgModule is an Angular
decorator that allows you to place all your imports, declarations, and bootstrap files for a
particular module in a single location. This makes bootstrapping all the files in large
applications very easy. NgModule has several metadata options that allow different things to
be imported, exported, and bootstrapped:

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:

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 { Chap3Component } from './app.component';
07
08 @NgModule({
09 declarations: [
10 Chap3Component
11 ],
12 imports: [

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.

Creating the Angular Bootstrapper


Now that you’ve looked at your component and module, you need some way to tell the rest of
your app about it. You do this by importing the bootstrapper through
platformBrowserDynamic from Angular.

Navigate to the file named main.ts in your app folder, which looks like this:

01 import { enableProdMode } from '@angular/core';


02 import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
03
04 import { AppModule } from './app/app.module';
05 import { environment } from './environments/environment';
06
07 if (environment.production) {
08 enableProdMode();
09 }
10
11 platformBrowserDynamic().bootstrapModule(AppModule);

31
FULLSTACK NOTES N.NAGAVENI

The imports are enableProdMode, platformBrowserDynamic, AppModule, and environment.


enableProdMode uses Angular’s optimizations for a production application.
platformBrowserDynamic is used to bootstrap the application together, using the application
module AppModule, as shown in the following code:

platformBrowserDynamic().bootstrapModule(AppModule);

The environment variable determines the state of the application—whether it should be


deployed in development mode or production mode.

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:

** NG Live Development Server is running on http://localhost:4200 **


Listing 21.1 shows the html index file that loads the application. Line 12 shows where the
message component gets applied.

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

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 { Chap3Component } from './app.component';
07
08 @NgModule({
09 declarations: [

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

01 import {Component} from 'angular2/core';


02 @Component({
03 selector: 'message',
04 template: `
05 <h1>Hello World!<h1>
06 `,
07 styles:[`
08 h1 {
09 font-weight: bold;
10 }
11 `]
12 })
13 export class Chap3component{
14 title = 'Chapter 21 Example';
15 }
Listings 21.4 and 21.5 show the compiled JavaScript code from the TypeScript files in
Listings 21.2 and 21.3.

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

12 return c > 3 && r && Object.defineProperty(target, key, r), r;


13 };
14 exports.__esModule = true;
15 var core_1 = require("@angular/core");
16 var Chap3Component = (function () {
17 function Chap3Component() {
18 this.title = 'Chapter 21 Example';
19 }
20 Chap3Component = __decorate([
21 core_1.Component({
22 selector: 'message',
23 template: "\n <h1>Hello World!<h1>\n "
24 })
25 ], Chap3Component);
26 return Chap3Component;
27 }());
28 exports.Chap3Component = Chap3Component;

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 I“m 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

Angular expressions are similar to TypeScript/JavaScript expressions in several ways, but


they differ in these ways:
Attribute evaluation: Property names are evaluated against the component model instead
of against the global JavaScript namespace.
More forgiving: Expressions do not throw exceptions when they encounter undefined or
null variable types; instead, they treat them as having no value.
No flow control: Expressions do not allow the following:
Assignments (for example, =, +=, -=)
The new operator
Conditionals
Loops
Increment and decrement operators (++ and --)
Also, you cannot throw an error inside an expression
Angular evaluates as expressions the strings used to define the values of directives. This
means you can include expression-type syntax within a definition. For example, when you set
the value of the ng-click directive in the template, you specify an expression. Inside that
expression, you can reference a component variable and use other expression syntax, as
shown here:
<span ng-click="myFunction()"></span>
<span ng-click="myFunction(var, 'stringParameter')"></span>
<span ng-click="myFunction(5*var)"></span>
Because the Angular template expressions have access to the component, you can also make
changes to the component inside the Angular expression. For example, this (click) directive
changes the value of msg inside the component model:
<span (click)="msg='clicked'"></span>
The following sections take you through some examples of using the expression capability in
Angular.
Using Basic Expressions
In this section, you get a chance to see how Angular expressions handle rendering of strings
and numbers. This example illustrates how Angular evaluates expressions that contain strings
and numbers as well as basic mathematical operators.
Listing 23.1 shows an Angular component. This component has a template that contains
several types of expressions wrapped in double curly brackets ({{}}). Some of the
expressions are just numbers or strings, some include the + operation to combine strings
and/or numbers, and one applies a === operator to compare two numbers.

52
FULLSTACK NOTES N.NAGAVENI

Listing 23.1 basicExpressions.component.ts: Basic Strings and Numbers with Simple


Math Operations in an Angular Template
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <h1>Expressions</h1>
07 Number:<br>
08 {{5}}<hr>
09 String:<br>
10 {{'My String'}}<hr>
11 Adding two strings together:<br>
12 {{'String1' + ' ' + 'String2'}}<hr>
13 Adding two numbers together:<br>
14 {{5+5}}<hr>
15 Adding strings and numbers together:<br>
16 {{5 + '+' + 5 + '='}}{{5+5}}<hr>
17 Comparing two numbers with each other:<br>
18 {{5===5}}<hr>
19 `,
20 })
21 export class AppComponent {}

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

34 lower = function(str: any){


35 return str.toLowerCase();
36 }
37 setValues = function(speed: any, vehicle: any){
38 this.speed = speed;
39 this.vehicle = vehicle;
40 }
41 }
Using TypeScript in Angular Expressions
This section takes a look at some additional TypeScript interactions within
the Component class.
As described previously, much of the TypeScript functionality is supported in Angular
expressions.
To illustrate this better, this example shows some array manipulation and uses the
TypeScript Math object within expressions.
Listing 23.3 implements an Angular component that uses Angular expressions that take
advantage of push() and shift()to display the arrays, show the array length, and manipulate
the array elements. Note that with Math added to the Component class, you are able to use
TypeScript Math operations directly in the expressions in lines 12 and 21.
Figure 23.3 shows the Angular web page rendered. Notice that as the links are clicked, the
arrays are adjusted and the expressions are reevaluated.

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

Listing 23.3 typescriptExpressions.component.ts: An Angular Component that Uses


Expressions Containing Arrays and Math
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <h1>Expressions</h1>
07 Array:<br>
08 {{myArr.join(', ')}}<br/>
09 <hr>
10 Elements removed from array:<br>
11 {{removedArr.join(', ')}}<hr>
12 <a (click)="myArr.push(myMath.floor(myMath.random()*100+1))">
13 Click to append a value to the array
14 </a><hr>
15 <a (click)="removedArr.push(myArr.shift())">
16 Click to remove the first value from the array
17 </a><hr>
18 Size of Array:<br>
19 {{myArr.length}}<hr>
20 Max number removed from the array:<br>
21 {{myMath.max.apply(myMath, removedArr)}}<hr>
22 `,
23 styles: [`
24 a{
25 color: blue;
26 cursor: pointer;
27 }
28 `],
29 })

58
FULLSTACK NOTES N.NAGAVENI

30 export class AppComponent {


31 myMath = Math;
32 myArr: number[] = [1];
33 removedArr: number[] = [0];
34 }

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

M: Month in year, 1 through 12


dd: Day in month, padded, 01 through 31
d: Day in month, 1 through 31
EEEE: Day in week, Sunday through Saturday
EEE: Day in Week, Sun through Sat
HH: Hour in day, padded, 00 through 23
H: Hour in day, 0 through 23
hh or jj: Hour in a.m./p.m., padded, 01 through 12
h or j: Hour in a.m./p.m., 1 through 12
mm: Minute in hour, padded, 00 through 59
m: Minute in hour, 0 through 59
ss: Second in minute, padded, 00 through 59
s: Second in minute, 0 through 59
.sss or ,sss: Millisecond in second, padded, 000–999
a: a.m./p.m. marker
Z: Four-digit time zone offset, -1200 through +1200
The format string for date can also be one of the following predefined names:
medium: Same as 'yMMMdHms'
short: same as 'yMdhm'
fullDate: same as 'yMMMMEEEEd'
longDate: same as 'yMMMMd'
mediumDate: same as 'yMMMd'
shortDate: same as 'yMd'
mediumTime: same as 'hms'
shortTime: same as 'hm'
The format shown here is en_US, but the format always matches the locale of
the Angular application.
Async Waits for a promise and returns the most recent value received. It then
updates the view.
Using Built-in Pipes

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

24 jsonObject = [{title: "mytitle"}, {title: "Programmer"}];


25 days=['Sunday', 'Monday', 'Tuesday', 'Wednesday',
26 'Thursday', 'Friday', 'Saturday'];
27 wait = new Promise<string>((res, err) => {
28 setTimeout(function () {
29 res('wait for it...');
30 },1000);
31 });
32 dairy = new Promise<string>((res, err) => {
33 setTimeout(function() {
34 res('dairy');
35 },2000)
36 })
37 }

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

24 str1: string = "Hello my name is"


25 name: string = "Brendan"
26 str2: string = "I like to"
27 likes: string[] = ['hike', "rappel", "Jeep"]
28 getLikes = function(arr: any){
29 var arrString = arr.join(", ");
30 return " " + arrString
31 }
32 imageSrc: string = "../assets/images/angelsLanding.jpg"
33 }

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

10 <button (click)="changeColor()">click me</button>


11 `
12 })
13 export class AppComponent {
14 twoColors: boolean = true;
15 changeColor = function(){
16 this.twoColors = !this.twoColors;
17 }
18 myBorder = "1px solid black";
19 }

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

59 if(this.counter < this.imageArray.length - 1){


60 this.counter++;
61 }else{
62 this.counter = 0;
63 }
64 this.imageUrl=this.imageArray[this.counter];
65 }
66 onKeyup(event:any){
67 this.upValues = event.key;
68 //this.upValues += event.target.value + ' | ';
69 }
70 onKeydown(event:any){
71 this.downValues = event.key;
72 //this.downValues += event.target.value + " | ";
73 }
74 keypress(event:any){
75 this.keypressValue = event.key;
76 //this.keypressValue += event.target.value + " | ";
77 }
78 move(event:any){
79 this.x = event.clientX;
80 this.y = event.clientY;
81 }
82 underTheScope(event:any){
83 if(event.type == "focus"){
84 this.view = "the text box is focused";
85 }
86 else if(event.type == "blur"){
87 this.view = "the input box is blurred";
88 }

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.

Using Built-in Directives


Much of the Angular functionality that you need to implement in HTML elements is provided
through built-in directives. These directives provide a wide variety of support for Angular
applications. The following sections describe most of the Angular directives, which fall into
three categories:

Component: A directive with a template

Structural: A directive that manipulates elements in the DOM

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

Table 25.1 Structural Directives

Directive Description

ngFor This directive is used to create a copy of a template for


each item within an iterable object. Here is an
example:<div *ngFor="let person opeople"></div>

ngIf When this directive is present in an element, that element is


added to the DOM if the value returns true. If the value returns
false, then that element is removed from the DOM,
preventing that element from using resources. Here is an
example:<div *ngIf="person"></div>

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:

<div *ngIf="myFunction(val)" >...</div>


<div *ngIf="myValue" >{{myValue}}</div>

ngFor is another example of a directive that uses the * symbol as a prefix to let Angular
know it’s there.

ngSwitch uses ngSwitchCase, which displays a section of HTML if a value or an expression


returns true. ngSwitch is surrounded by [] as a form of one-way data binding to pass the data
to each ngSwitchCase for evaluation. The following is an example of the syntax for
ngSwitch:

<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

structural.component.ts: Structural Built-in Functions

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


02
03 @Component({
04 selector: 'app-root',
05 template: `
06 <div *ngIf="condition">condition met</div>
07 <div *ngIf="!condition">condition not met</div>
08 <button (click)="changeCondition()">Change Condition</button>
09 <hr>
10 <template ngFor let-person [ngForOf]="people">
11 <div>name: {{person}}</div>
12 </template>
13 <hr>
14 <h3>Monsters and where they live</h3>
15 <ul *ngFor="let monster of monsters">
16 {{monster.name}}:
17 {{monster.location}}
18 </ul>
19 <hr>
20 <div [ngSwitch]="time">
21 <span *ngSwitchCase="'night'">It's night time
22 <button (click)="changeDay()">change to day</button>
23 </span>
24 <span *ngSwitchDefault>It's day time
25 <button (click)="changeNight()">change to night</button></span>
26 </div>
27 `
28 })

82
FULLSTACK NOTES N.NAGAVENI

29 export class AppComponent {


30 condition: boolean = true;
31 changeCondition = function(){
32 this.condition = !this.condition;
33 }
34 changeDay = function(){
35 this.time = 'day';
36 }
37 changeNight = function(){
38 this.time = 'night'
39 }
40 people: string[] = [
41 "Andrew", "Dillon", "Philipe", "Susan"
42 ]
43 monsters = [
44 { name: "Nessie",
45 location: "Loch Ness, Scotland" },
46 { name: "Bigfoot",
47 location: "Pacific Northwest, USA" },
48 { name: "Godzilla",
49 location: "Tokyo, sometimes New York" }
50 ]
51 time: string = 'night';
52 }

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:

<form #formName="ngForm" (ngSubmit)="onSubmit(formName)"> </form>


ngStyle
This directive updates the styles of an HTML element.
Example:
01 import { Component } from '@angular/core';
02
03 @Component({
04 selector: 'app-root',
05 templateUrl: './attribute.component.html',
06 styleUrls: ['./attribute.component.css']
07 })
08 export class AppComponent {
09 colors: string[] = ["red", "blue", "green", "yellow"];
10 name: string;
11 color: string = 'color';
12 isDisabled: boolean = true;

84
FULLSTACK NOTES N.NAGAVENI

13 classes:string[] = ['bold', 'italic', 'highlight'];


14 selectedClass:string[] = [];
15 enabler(){
16 this.isDisabled = !this.isDisabled;
17 }
18 addClass(event: any){
19 this.selectedClass = [];
20 var values = event.target.options;
21 var opt: any;
22
23 for (var i=0, iLen = values.length; i<iLen; i++){
24 opt = values[i];
25
26 if (opt.selected){
27 this.selectedClass.push(opt.text);
28 }
29 }
30 }
31 }
Listing 25.3 attribute.component.html: An Angular Template for the Attribute Component

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

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


@Directive({
selector: '[myDirective]'
})
export class myDirective { }
Creating a Custom Attribute Directive
You can define a limitless number of types of custom directives, which makes Angular
incredibly extensible. Custom directives are the most complex portion of Angular to explain.
The best way to get you started is to show you an example of custom directives to give you a
feel for how they can be implemented and interact with each other.
This section shows how to implement a custom attribute directive. The zoom directive
created in this example is designed to add custom functionality to whatever image it is
applied to. With this directive applied, you can scroll over an image with the mouse wheel to
make the element grow or shrink in size.
Listing 26.1 zoom.component.ts: A Structural Directive
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 images: string[] = [
10 '../assets/images/jump.jpg',
11 '../assets/images/flower2.jpg',
12 '../assets/images/cliff.jpg'
13 ]
14 }
Listing 26.2 zoom.directive.ts: A Custom Attribute Directive
01 import { Directive, ElementRef, HostListener, Input, Renderer }
02 from '@angular/core';

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

Figure 26.1 Applying a custom attribute directive


Creating a Custom Directive with a Component
Angular components are also a type of directive. What distinguishes a component from a
directive is that components use an HTML template to generate a view. But because a
component underneath is just a directive, it can be applied to HTML elements to add custom
functionality in some really cool ways.
Angular offers a built-in directive called ng-content. This directive allows Angular to take
existing HTML from between two element tags that use a directive and use that HTML
within the components template. The syntax of ng-content is as follows:
<ng-content></ng-content>
The example in this section shows how to use a component as a custom directive to change
how the element looks with a containing template.
This example implements a custom directive container that is designed to add a surrounding
“container” HTML template to the element it is being applied to. This directive has two
inputs title and description that can be used to give the host element a description and title.
Listing 26.5 shows the root component, which displays various HTML elements. These
elements have the container directive applied, which adds a header with an optional title, a
footer with an optional description, and borders to each element.
Listing 26.5 app.component.ts: The Root Component
01 import { Component } from '@angular/core';
02

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

06 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit,


07 sed do eiusmod tempor incididunt ut labore </p>
08 </span>
09 <span container>
10 <div class="diver">
11 </div>
12 </span>
Listing 26.7 shows the CSS for the root component. It sets a max image height to keep the
size of the image smaller. It also sets some default styling for the class diver so that it is
visible to the user.
Listing 26.7 app.component.css: CSS for the Root Component
01 img{ height: 300px; }
02 p{ color: red }
03 .diver{
04 background-color: forestgreen;
05 height: 300px;
06 width: 300px;
07 }
Listing 26.8 shows the container directive. This directive has the selector container and the
inputs title and description. This directive imports Directive, Input,
and Output from @angular/core to provide the functionality this directive needs.
Listing 26.8 container.component.ts: A Component that Defines the Container
01 import { Component, Input, Output } from '@angular/core';
02
03 @Component({
04 selector: '[container]',
05 templateUrl: './container.component.html',
06 styleUrls: ['./container.component.css']
07 })
08 export class ContainerComponent {
09 @Input() title: string;
10 @Input() description: string;

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.

Figure 26.2 Custom component directive

Implementing Angular Services in Web Applications


• One of the most fundamental components of Angular functionality is services.
• Services provide task-based functionality to applications. You can think of a service as
a chunk of reusable code that performs one or more related tasks.

93
FULLSTACK NOTES N.NAGAVENI

• Angular provides several built-in services and also allows you to create your own
customized services.

Understanding Angular Services


The purpose of a service is to provide a concise bit of code that performs specific tasks. A
service does something as simple as providing a value definition or as complex as providing
full HTTP communication to a web server.

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.

Using the Built-in Services


Angular provides several built-in services that are included in the Angular module, using
dependency injection. Once included within a module, services can be used throughout an
application.

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.

Table 28.1 Common Services That Are Built in to Angular


1. animate
Provides animation hooks to link into both CSS- and JavaScript-based animations

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])

patch(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

Method An HTTP method, such as GET or POST.

url The URL of the resource that is being requested.

Params Parameters to be sent. This can be a string in the following format:


?key1=value1&key2=value2&...
Or it can be an object, in which case it is turned into a JSON string.

95
FULLSTACK NOTES N.NAGAVENI

Body Data to be sent as the request message body.

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.

3. catch: Specifies a function to gracefully handle errors in the observable sequence.

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

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


02 import { Observable } from 'rxjs/Observable';
03 import { Http } from '@angular/http';
04
05 import 'rxjs/Rx';
06
07 @Component({
08 selector: 'app-root',
09 templateUrl: './app.component.html',
10 styleUrls: ['./app.component.CSS']

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.

Listing 28.4 http.component.html: An Angular Template that Displays a List of Users


Received from the Database

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

Implementing a Simple Mock Server Using the http Service


Note
To create the mock service, you need to run the following command from the console:

npm install Angular-in-memory-web-api

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

01 import { InMemoryDbService } from 'angular-in-memory-web-api';


02 export class InMemoryDataService implements InMemoryDbService {
03 createDb() {
04 const users = [
05 {
06 "id": 1,
07 "userName": "brendan",
08 "email": "[email protected]"
09 },
10 {

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 }

Listing 28.7 createDelete.component.ts: An Angular Component that Gets and Modifies


a List of Users with the http Service

01 import { Component, OnInit } from '@angular/core';


02 import { Observable } from 'rxjs/Observable';
03 import { Http } from '@angular/http';
04
05 import 'rxjs/Rx';
06
07 import { UserService } from './user.service';
08
09 @Component({
10 selector: 'app-root',
11 templateUrl: './app.component.html',
12 styleUrls: ['./app.component.CSS'],
13 providers: [UserService]
14 })

102
FULLSTACK NOTES N.NAGAVENI

15 export class AppComponent implements OnInit {


16 users = [];
17 selectedUser;
18
19 constructor(private UserService: UserService){ }
20
21 ngOnInit(){
22 this.getUsers()
23 }
24
25 getUsers(): void {
26 this.UserService
27 .getUsers()
28 .then(users => this.users = users)
29 }
30
31 deleteUser(user){
32 this.UserService
33 .deleteUser(user.id)
34 .then(() => {
35 this.getUsers();
36 });
37 }
38
39 createUser(userName, email){
40 this.selectedUser = null;
41 let user = {
42 'userName': userName.trim(),
43 'email': email.trim()
44 };

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

01 import { Injectable } from '@angular/core';


02 import { Http } from '@angular/http';
03 import 'rxjs/add/operator/toPromise';
04
05 @Injectable()
06 export class UserService {
07 url = 'api/users'
08 constructor(private http: Http) { }
09
10 getUsers(): Promise<any[]> {
11 return this.http.get(this.url)
12 .toPromise()
13 .then(response => response.JSON().data)
14 .catch(this.handleError)
15 }
16 deleteUser(id: number): Promise<void>{
17 return this.http.delete(`${this.url}/${id}`)
18 .toPromise()

104
FULLSTACK NOTES N.NAGAVENI

19 .then(() => null)


20 .catch(this.handleError);
21 }
22 createUser(user): Promise<any>{
23 return this.http
24 .post(this.url, JSON.stringify({
25 userName: user.userName,
26 email: user.email
27 }))
28 .toPromise()
29 .then(res => res.JSON().data)
30 .catch(this.handleError)
31 }
32
33 private handleError(error: any): Promise<any> {
34 console.error('An error occurred', error);
35 return Promise.reject(error.message || error);
36 }
37
38 }
Listing 28.9 implements an Angular template that utilizes ngFor to create a list of users to be
displayed within the application.
01 <div>
02 <label>user name:</label> <input #userName />
03 <label>user email:</label> <input #userEmail />
04 <button (click)="createUser(userName.value, userEmail.value);
05 userName.value=''; userEmail.value=''">
06 Add
07 </button>
08 </div>
09

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.

Listing 28.10 createDelete.component.CSS: A CSS Stylesheet 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 }
12 .selected{
13 background-color: steelblue;
14 color: white;
15 }

106
FULLSTACK NOTES N.NAGAVENI

Listing 28.11 app.module.ts: An Angular Module that Imports InMemoryWebApiModule to


Be Used with the Application
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 import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
06
07 import { AppComponent } from './app.component';
08 import { InMemoryDataService } from './data.service'
09
10 @NgModule({
11 declarations: [
12 AppComponent
13 ],
14 imports: [
15 BrowserModule,
16 FormsModule,
17 HttpModule,
18 InMemoryWebApiModule.forRoot(InMemoryDataService)
19 ],
20 providers: [],
21 bootstrap: [AppComponent]
22 })
23 export class AppModule { }

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

01 import { InMemoryDbService } from 'angular-in-memory-web-api';


02 export class InMemoryDataService implements InMemoryDbService {
03 createDb() {
04 const users = [
05 {
06 "id": 1,
07 "userName": "brendan",
08 "email": "[email protected]"
09 },
10 {
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 }

Listing 28.13 update.component.ts: An Angular Component that Uses http to Update


Data in the Server

01 import { Component, OnInit } from '@angular/core';

108
FULLSTACK NOTES N.NAGAVENI

02 import { Observable } from 'rxjs/Observable';


03 import { Http } from '@angular/http';
04
05 import 'rxjs/Rx';
06
07 import { UserService } from './user.service';
08
09 @Component({
10 selector: 'app-root',
11 templateUrl: './app.component.html',
12 styleUrls: ['./app.component.CSS'],
13 providers: [UserService]
14 })
15 export class AppComponent implements OnInit {
16 users = [];
17 selectedUser;
18
19 constructor(private UserService: UserService){ }
20
21 ngOnInit(){
22 this.getUsers()
23 }
24
25 getUsers(): void {
26 this.UserService
27 .getUsers()
28 .then(users => this.users = users)
29 }
30
31 selectUser(user){

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

01 import { Injectable } from '@angular/core';


02 import { Http } from '@angular/http';
03 import 'rxjs/add/operator/toPromise';
04
05 @Injectable()
06 export class UserService {
07 url = 'api/users'
08 constructor(private http: Http) { }
09
10 getUsers(): Promise<any[]> {
11 return this.http.get(this.url)
12 .toPromise()
13 .then(response => response.JSON().data)
14 .catch(this.handleError)
15 }
16 updateUser(user): Promise<void>{
17 console.log(user);
18 const url = `${this.url}/${user.id}`;

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 }

Listing 28.15 update.component.html: An Angular Template that Displays a List of


Users and Can Be Updated

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 }

Figure 28.3 Implementing a simple mock server to update items in a database

Changing Views with the router Service


The router service enables you to change views on the web application so that you can route
back and forth between components. This can be done as a full-page view change or can
change smaller segments of a single-page application. The router service is in an external
Angular module called RouterModule and needs to be included in the applications module to
be used throughout the application.

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:

Const routes: Routes = [


{
Path: '',
Component: myComponent
},
{
Path: 'route',
Component: myComponent

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

Path Shows where in the router tree this route belongs


Component Defines which component will be loaded once routed

redirectTo Redirects to the defined path instead of the current route

outlet Specifies the name used for the RouterOutlet that renders the route

canActivate Protects the route by preventing activation when false

canActivateChild Protects the child routes by preventing activation when false

canDeactivate Specifies whether the route can be deactivated

canLoad Allows you to protect specific modules from being loaded in the route

Data Allows for data to be passed into the component

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.)

loadChildren Allows for lazy loading of child routes

runGuardsAndResolvers Defines when the guards and resolvers are run

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

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 { AppRoutingModule } from './app-routing.module';
07 import { AppComponent } from './app.component';
08 import { Route2Component } from './route2/route2.component';
09 import { HomeComponent } from './home/home.component';
10
11 @NgModule({
12 declarations: [
13 AppComponent,
14 Route2Component,

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

01 import { NgModule } from '@angular/core';


02 import { Routes, RouterModule } from '@angular/router';
03 import { Route2Component } from './route2/route2.component';
04 import { HomeComponent } from './home/home.component';
05 const routes: Routes = [
06 {
07 path: '',
08 component: HomeComponent
09 },

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

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


02
03 @Component({
04 selector: 'app-root',
05 template: '<router-outlet></router-outlet>'
06 })
07 export class AppComponent {}
Listing 28.20 home.component.html: An HTML File that Is the Default Displayed Route
01 <p>
02 Home Route works!
03 </p>
04 <a routerLink="/route2">Route 2</a>
Listing 28.21 shows the home component file. This file is as barebones as a component gets.
Its main purpose is to load the template file and make it available to the router.

118
FULLSTACK NOTES N.NAGAVENI

Listing 28.21 home.component.ts: An Angular Component that Includes a Template


with a Route

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


02
03 @Component({
04 selector: 'app-home',
05 templateUrl: './home.component.html',
06 styleUrls: ['./home.component.CSS']
07 })
08 export class HomeComponent{}
Listing 28.22 shows the route2 component template file. This file displays a message that lets
the user know the route is working, followed by a link that uses routerLink to navigate the
user to a separate view.

Listing 28.22 route2.component.html: A CSS File that Styles the Application

Click here to view code image

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.

Listing 28.23 route2.component.ts: An Angular Component that Includes a Template with a


Route

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


02

119
FULLSTACK NOTES N.NAGAVENI

03 @Component({
04 selector: 'app-route2',
05 templateUrl: './route2.component.html'
06 })
07 export class Route2Component {}

Implementing a Router with Parameters

Listing 28.36 app-routing.module.ts: An Angular Template that Assigns Router


Parameters

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


02 import { Router, ActivatedRoute, Params } from '@angular/router';
03
04 @Component({
05 selector: 'app-page1',
06 templateUrl: './page1.component.html'
07 })
08 export class Page1Component {
09 text='';
10 constructor(
11 private route: ActivatedRoute,
12 private router: Router,
13 ){ }
14 gotoPage2(){
15 this.router.navigate(
16 ['/page2', this.text],
17 {
18 relativeTo: this.route,

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.

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


02
03 @Component({
04 selector: 'app-root',
05 template: '<router-outlet></router-outlet>'
06 })
07 export class AppComponent { }
Listing 28.38 page1.component.ts: An Angular Component that Navigates to Page 2 with
Parameters

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


02 import { Router, ActivatedRoute } from '@angular/router';
03
04 @Component({
05 selector: 'app-page1',
06 templateUrl: './page1.component.html'
07 })
08 export class Page1Component {
09 text='';
10 constructor(
11 private route: ActivatedRoute,
12 private router: 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>

Listing 28.40 page2.component.ts: An Angular Component that Displays Router


Parameters on the View

01 import { Component, OnInit } from '@angular/core';


02 import { Router, ActivatedRoute } from '@angular/router';
03
04 @Component({
05 selector: 'app-page2',
06 templateUrl: './page2.component.html'
07 })
08 export class Page2Component implements OnInit {
09 text;

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 }

Listing 28.41 page2.component.html: Parameters Passed from the Router


01 <h3>Params From Page 1</h3>
02 <p>{{text}}</p>
03 <button (click)="goBack()" >back</button>
Figure 28.6 Implementing the http service to allow Angular components to interact with a
web server

123

You might also like