Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Angular-13 Full

Download as pdf or txt
Download as pdf or txt
You are on page 1of 279

TypeScript

Setup Environment for Typescript


1. Download and Install Node.js
- Node.js is required for Package Manager
- Node.js provide "NPM" as Package Manager
Yarn
NuGet
RubyGems
Bower etc..

https://nodejs.org/en/
[Windows 8+, any another OS]

- Download 16x version

2. Test Node.js and NPM versions from your command prompt

C:\>node -v 12+
C:\>npm -v 6+

3. Download and Install TypeScript on your PC

C:\>npm install -g typescript


C:\>tsc -v
4.5.5 version

4. Download and Install "Visual Studio Code" editor

https://code.visualstudio.com/

* Not visual studio - It is Visual Studio Code

5. Download and Install following Extensions for VS Code

- Live Server [Ritwik Dey]


- vscode-icons
- Intellisense for CSS class Names in HTML

Create a new Project for TypeScript


===========================
1. Create a new folder for project at any location on your PC

D:\TypeScript-Project

2. Open folder in Visual Studio Code

3. Open Terminal in VS Code [Command Terminal]


[Terminal Menu --> New Terminal ]
Make sure that you changed terminal from
"Power Shell to Command Prompt"

PS D:\> Power Shell

4. Run the following command in terminal to create package.json

D:\Typescript-Project> npm init -y

5. Run the following command in terminal to create tsconfig.json

D:\>Typescript-Project> tsc -init

FAQ: What is Package.json?


Ans : It comprises of meta data.
Information about your project, like version, kewords,
dependencies..

FAQ: What is tsconfig.json?


Ans: It configures the rules for typescript configuration in project.
It includes details like
a) Module System
b) Target JavaScript Version
c) Language rules etc.. [tsLint.json - obsolete] etc..

6. Add following folders into projects


a) public
b) src

public : comprises of static resources like html, images, text


docs..
src : comprises of dynamic resources like css, ts, js etc..

7. Go to public folder and add a new HTML file by name


"index.html"
8. Go to src folder and add a new file
"Index.ts"
function bodyload(){
document.getElementById("container").innerHTML = 'Typescript
running..';
}

9. Transcompile into JavaScript

D:...src> tsc index.ts

[This will generate index.js ]


10. Link JavaScript file to Index.html

<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script src="../src/index.js"></script>
</head>
<body onload="bodyload()">
<h2>Welcome to TypeScript</h2>
<div id="container"></div>
</body>
</html>

Typescript Language Basics


package.json
tsconfig.json

- Variables
- Data Types
- Operators
- Statements
- Functions
Variables
- Variables in Typescript are same as in JavaScript.
- Variables are declared by using
a) var
b) let
c) const
- Variables in typescript are strongly typed.

Syntax:
var variableName:dataType;

Ex: JavaScript
var x = 10; // x is number
x = "A"; // x is string
x = true; // x is boolean

Data Types
- Primitive Types
a) number
b) boolean
c) string
d) null
e) undefined
- Non Primitive Types
a) Array
b) Object
c) Map

Note: If data type is not defined for variable in typescript, then it is


configured as "any" type.

FAQ: What is Type Inference?


Ans: It is a technique of configuring data type for variable according
to the value initialized.

Syntax:
let username = "john"; // type is string
let age = 22; // type is number

FAQ: Configuring data type for variable in typescript, is it mandatory?


Ans: No.

FAQ: What is union of Types?


Ans: It is the technique of configuring a variable to handle multiple
data types.

Syntax:
let username:string | number;
username = "john"; // valid
username = 1001; // valid
username = true; // invalid

Ex:
1. Write the following code into "Index.ts"

let ProductName:string = "Samsung TV";


let Price:number = 45000.55;
let Stock:boolean = true;

console.log(`Name=${ProductName}\nPrice=${Price}\nStock=${(Stoc
k==true)?'Available':'Out of Stock'}`);

2. Transcompile from terminal

> tsc index.ts

3. Run the JavaScript file

> node index.js

Summary :
========
1. number
2. string
3. boolean
4. null
5. undefined

let variableName:number;
let variableName:string | number;
let variableName:any;

Non-Primitive Types
===============
1. Array
2. Object
3. Map

JavaScript:
let collection = [ ];
let collection = new Array();

JavaScript array can handle various types of values.


JavaScript array size can change dynamically.

let collection = [10, "A", true]; // valid

Array Methods:
join(), slice(), splice(), indexOf(), lastIndexOf(), pop(), push() etc

TypeScript Array
=============
- You can design array in typescript to handle similar type of values or
with combination of various types of values.

Syntax:
let collection:string[] = [ ]; // only string
let collection:number[] = []; // only number

- You can also configure union of types for array

let collection:string[] | number[] = [];

FAQ: What is difference between array "[ ]" and Array()?


Ans:
let collection:string[] = [ ]; // meta character
let collection:string[] = new Array(); // constructor

- Array() allows to define size of array.


- It will not allow to initialize various types of values even when
the data type is configured as "any" type.

Syntax:
let collection:any[] = [10, 'john', true]; // valid
let collection:any[] = new Array(10, 'john'); // invalid
only number.
let collection:any[] = new Array('john', 10); // invalid
only string.

- Array() will allow to assign various types of value.

Syntax:
let collection:any[] = new Array();
collection[0] = 10;
collection[1] = 'john'; /// valid

FAQ: Can we define union of types for array?


Ans: Yes. But you can't initialize various values into array.
You can only assign union of values.

Syntax:
let collection:string[] | number[] = [10, 'john']; // invalid

let collection:string[] | number[] = [];


collection[0] = 10;
collection[1] = 'john'; //valid

FAQ: What is a Tuple?


Ans: Tuple is a collection of various types of values.

Syntax:
let collection: any[] = [ ];

Note: Array handling and manipulation is same like in JavaScript.


All array methods are same.

Reading
- toString()
- join()
- slice()
- find()
- filter()
- map()

Add
- push()
- unshift()
- splice()

Remove
- pop()
- shift()
- splice()
Ex:
let categories:string[] = ['All', 'Electronics', 'Footwear'];
categories.push('Fashion');
categories.map(function(value){
console.log(value);
})

Object, Maps

https://github.com/Sharma-NareshIT/angular13

How to define object in TypeScript?

-Typescript don't have special data type for object.


-You have to use "any" as type.
- All features and functions are same as JavaScript.

Syntax:
let obj:any = { };

Ex:
let product:any = {
"Name": "Samsung TV",
"Price": 56000.44,
"Stock": true,
"ShippedTo": ['Delhi','Hyd'],
"Qty":2,
"Total":function(){
return this.Qty * this.Price;
},
"Print":function(){

console.log(`Name=${this.Name}\nPrice=${this.Price}\nStock=${this.S
tock}\nQty=${this.Qty}\nTotal=${this.Total()}\nShippedTo=${this.Ship
pedTo}`);
}
}
product.Print();

How to define array of objects?


- There is no specific data type for array of objects.
- You have to use "any" as type.

Syntax:
let products:any[] = [ { }, { }, { }, ... ];
Ex:
let products:any[] = [
{Name: 'TV', Price:56700.44},
{Name: 'Mobile', Price: 45000.33}
];
console.log(`Mobile Price=${products[1].Price}`);

How to define a Map type?


- There is no specific data type for Map.
- You have to use "any" as type.

Syntax:
let data:any = new Map();
data.set()
data.get()
data.delete()
data.clear()

Ex:
let products:any = new Map();
products.set(1, 'Samsung TV');
products.set(2, 'Mobile');

console.log(products.get(2));

FAQ: What is difference between Object and Map?

Object:
- It is a key and value collection.
- Keys are only string type.
- No size for Keys
- You need explicity iterators to read keys and values.
- It is slow in reading and rendering.

Map:
- It is also a key and value collection.
- Keys are configured with any type.
- You can configure size for keys
- Map provides implicit iterators for reading keys and values.
[keys(), values(), entries()]
- It is faster in reading and rendering.

Ex:
let products:any = new Map();
products.set(1, 'Samsung TV');
products.set(2, 'Mobile');

console.log(products.get(2));

How to define date?


- There is no specific data type for date.
- You have to use "any" as type with Date() constructor.
Syntax:
let dateofBirth:any = new Date('yy-mm-dd');

- All date functions are same as in JavaScript.

getHours()
getMinutes()
getSeconds()
getMilliSeconds()
getDay()
getDate()
getMonth()
getFullYear()

similarly the set() methods.

Ex:
let Manufactured:any = new Date('2022-01-18');
console.log(`Manufactured Year=${Manufactured.getFullYear()}`);

How to define Regular Expression?


- There is no specific data type for regular expression.
- You have to use "any" as type with expression enclosed in "/ /".
Syntax:
let regExp:any = /[A-Z]{4,10}/;

- Regular expression is verified by using "match()".

Ex:
let password:string = 'JOHN';
let regExp:any = /[A-Z]{4,10}/;

if(password.match(regExp)) {
console.log('Password Verified..');
} else {
console.log('Error: Password 4 to 10 chars Uppercase Only');
}

Summary:
- handling various data types
number
string
null
boolean
undefined
array
object
map
regular expression
date
array of object

let name:number[ ] = [ ]
let name:any[] = [];
let exp:any = / /;

- Statements are same as in JavaScript

Selection Statements if, else, switch, case, default


Looping Statements for, while, do while
Iteration Statements for..in , for..of
Jump Statements break, continue, return
Exception Handling try, catch, throw, finally

- Operators are same as in JavaScript


Arithematic Operators
Assignment Operators
Logical Operators
Comparision Operators
Bitwise Operators etc..

- Functions and Parameters are same as in JavaScript


Parameterized functions
Function with return
Function with "Rest" parameters
Arrow functions
Function Recurssion
Function Colsure
Anonymous functions

Summary for Language Basics:


1. Variables
2. Data Types
3. Operators
4. Statements
5. Functions

Typescript OOP
- TypeScript is an OOP language.
- It supports all features of OOP.

Contracts in OOP
- Contract defines rules for designing a component in OOP.
- Contracts are designed by using "interface".

Syntax:
interface InterfaceName
{
// rules
}

- Contract can contain only declaration of rules.

Name:string = 'TV'; // invalid


Name:string;

Ex:
interface ProductContract
{
Id:number;
Name:string;
Cost:number;
Stock:boolean;
}

let product:ProductContract = {
"Name": "Samsung TV",
"Cost": 56000.44,
"Stock": true,
"Id": 1,
}
Contracts in OOP
- Contract defines rules for designing any component in OOP.
- Contracts are defined by using "interface"
- Interface can contain only declaration.

Syntax:
interface Name
{
}

Ex:
interface ProductContract
{
Id:number;
Name:string;
Cost:number;
Stock:boolean;
}

let product:ProductContract = {
"Name": "Samsung TV",
"Cost": 56000.44,
"Stock": true,
"Id": 1,
}
Optional Rules in Contract:
- Every rule defined in contract is mandatory
- TypeScript contract can configure optional rules.
- Optional rules are required to design goal of any module or
component.
- Mandatory rules are required to configure the objective of
component.
- You can configure optional rules by using
"null reference character - ?"

? = zero or one occurance


+ = one or more occurrance
* = zero or more occurance
Syntax:
interface Name
{
property?:dataType; // optional
property:dataType; // mandatory
}

Ex:
interface ProductContract
{
Id:number;
Name:string;
Cost:number;
Stock?:boolean; // optional
}

let product:ProductContract = {
"Name": "Samsung TV",
"Cost": 56000.44,
"Id": 1,
}

Readonly Rules in Contract:


- Every rule defined in contract can be re-assigned with a new value
after initialization of value.
- You can restrict assigning of value after initialization by using
"readonly"

Syntax:
interface Name
{
readonly Property:dataType;
}

Ex:
interface ProductContract
{
Name:string;
readonly Price:number;
}
let tv:ProductContract = {
Name : "Samsung TV",
Price: 56000.55
}
tv.Name = "Samsung LED TV";
tv.Price = 70000.55; // invalid - readonly
console.log(`Name=${tv.Name}\nPrice=${tv.Price}`);

Rules for Methods in Contract:


- Every component comprises of properties and methods.
- Data is stored in properties and functionality is defined by using
methods.
- Contract can contain rules for methods.
- Every contract method rule can contain only declaration.
[ no definition ]
- Method rule must define the return type.
- Method rule can be optional.

Syntax:
interface Name
{
method():dataType;
method?():void;
}

Ex:
interface ProductContract
{
Name:string;
Price:number;
Qty:number;
Total():number;
Print?():void;
}
let tv:ProductContract = {
Name : "Samsung TV",
Price: 56000.55,
Qty: 2,
Total() {
return this.Qty * this.Price;
},
Print() {

console.log(`Name=${this.Name}\nPrice=${this.Price}\nQty=${this.Qt
y}\nTotal=${this.Total()}`) ;
}
}
tv.Print();

Extending Contracts:
- Every contract is configure with set of rules.
- You can extend the contract without modifying the existing set of
rules and contract.
- A contract can be extended by using "extends" keyword.
- Contract supports extending
a) Single
b) Multiple
c) Multi Level

- Single : A contract is extended by another contract.

interface A
{
}
interface B extends A
{
}

- Multi Level : An extended contract is extended again.


interface C extends B
{
}

- Multiple : A contract can extend more than one contract.

interface D extends A, B, C
{
}

Ex:
interface ECMA2015
{
Operators:string;
Parameter:string;
}
interface ECMA2016 extends ECMA2015
{
Functions:string;
}
interface ECMA2017 extends ECMA2016
{
OOP:string;
Functions:string;
}
let JavaScript:ECMA2017 = {
Parameter : '',
Operators: '',
OOP: '',
Functions: ''
}

Ex:
interface TextEffects
{
Align:string;
}
interface BackEffects
{
BgColor:string;
}
interface Effects extends TextEffects, BackEffects
{
Border:string;
}
let css : Effects = {
Align : 'center',
BgColor: 'red',
Border : '2px solid red'
}
TypeScript Class
Class in OOP
- Configuring class is similar to JavaScript
- Class members also same
a) Properties
b) Methods
c) Accessors get(), set()
d) Constructor
- TypeScript class supports 2 types of members.
a) Static Member
b) Non Static Member

What is static?
- Static refers to contineous memory.
- Memory allocate for first object will continue for next object.
- It uses more memory
- It can lead to memory leaks.
- Burden for application
- TypeScript static members are defined by using "static" keyword
- Static members are accessible within the class or outside class by
using class name.

Syntax:
class className
{
static s = 0;
}
className.s ;

What is non-static?
- It refers to discreet memory.
- It uses disconnected memory.
- Memory is newly allocated for every object.
- Non static members are accessible within the class by using "this"
keyword and outside the class by using instance of class.

Syntax:
class Name
{
n = 0; // non-static
static s =0; // static
this.n;
}
let obj = new Name();
obj.n;

Ex:
class Demo
{
static s = 0;
n = 0;
constructor(){
Demo.s = Demo.s + 1;
this.n = this.n + 1;
}
Print(){
console.log(`s=${Demo.s} n=${this.n}`);
}
}
let obj1 = new Demo();
obj1.Print();
let obj2 = new Demo();
obj2.Print();
let obj3 = new Demo();
obj3.Print();

- TypeScript class provides code level security for members in class by


using "Access Modifers"
a) public
b) private
c) protected

public member:
- It is public in access.
- It is accessible from any location and through any object reference.
- It is the default access modifier for members in TypeScript class.
- You can access by using base class object or derived class object.
- You can access in base or in derived class.
- You can access within the class or outside class.

private member:
- It is private in access.
- You can access only within the defined class.
- It is not accessible outside class.

protected member:
- It is protected in access.
- You can access with in the defined class.
- You can access outside class only with in dervied class by using
derived class object.
- It is protected for derived members.

Summary
access public private protected
--------------------------------------------------------------------------------------------
----
with in class yes yes yes

outside class yes no yes

using base object yes no no

using derived object yes no no

[derived object in yes no yes


derived class]

[base object in yes no no


derived class]

Ex:
class Product
{
public Name:string = 'Samsung TV';
private Price:number = 45600.55;
protected Stock:boolean = true;
public Print():void{

console.log(`Name=${this.Name}\nPrice=${this.Price}\nStock=${this.S
tock}`);
}
}
class ProductExtention extends Product
{
public Print(): void {
let obj = new ProductExtention();
obj.Name;
obj.Stock;
}
}

- TypeScript Properties, Methods, Accessors and Constructor all are


same as in JavaScript.

FAQ: Can we define a variable in class?


Ans : No

FAQ: Can we define a function in class?


Ans: No

FAQ: Why we can't have a variable and function in class?


Ans: Class is template and template contains only mutable
components.
Variable and function are immutable.

FAQ: What is the rule for constructor?


Ans: A derived class constructor must have super call.

class Base
{
constructor(){

}
}
class Derived extends Base
{
constructor() {
super();
}
}

Templates in OOP
- A template comprises of sample data and logic, which you can
implement and customize according to the requirements.

- Templates are used in "Rollouts".


- Templates are configured by using "Abstract Class".
- Template uses a contract. It implements contract and initializes
functionality.

Syntax:
interface IName
{
}
class className impements IName
{
}

- A class can implement multiple contracts.

class className implements Contract1, Contract2, ...


{
}

- A template may contain members defined with functionality as well


as the members need to be implemented.

- If any member need to be imlemented then it is marked with


"abstract" keyword.

- If a class contains at least one abstract member then the class must
be marked as "abstract".

Syntax:
abstract class Template
{
public Name:string = ' ';
public abstract Total():number;
}

Note:
1. A contract can extend another contract.
2. A class can implement contract.
3. A class can implement multiple contracts.
4. A class can extend another class.

- A template comprises data structure and it is hidden for


components which are implementing the template.

- The process of hiding data structure and providing only the


component for implementation is known as "Abstraction".

Ex:
interface ProductContract
{
Name:string;
Price:number;
Qty:number;
Total():number;
Print():void;
}
interface CategoryContract
{
CategoryName:string;
}
abstract class ProductTemplate implements ProductContract,
CategoryContract
{
public Name: string = '';
public Price: number = 0;
public Qty: number = 0;
public CategoryName: string = '';
public abstract Total():number;
public abstract Print(): void;
}
//------------------------- Developer Implements --------------------------

class ProductComponent extends ProductTemplate


{
Name = 'Samsung TV';
Price = 66000.44;
Qty = 2;
Total(){
return this.Qty * this.Price;
}
Print(){

console.log(`Name=${this.Name}\nPrice=${this.Price}\nQty=${this.Qt
y}\nTotal=${this.Total()}`);
}
}

let tv = new ProductComponent();


tv.Print();

Module System
- Export
- Default
- Import
CommonJS
Require JS
UMD
AMD

contract => implements => template => extends => component

FAQ: What is Reflection?


Ans : It is a technique of accessing the members of class.
It returns information about class members.

FAQ: What is Refaction [Refactor]?


Ans : It is a techique of encapsulating a set of statements and
extracting into a method.

Ex:
1. Add a new folder "library"
2. Add sub folders
- contracts
- templates
- components

3. contracts
ProductContract.ts
export interface ProductContract
{
Name:string;
Price:number;
Qty:number;
Total():number;
Print():void;
}
4. templates
ProductTemplate.ts

import { ProductContract } from '../contracts/ProductContract';

export abstract class ProductTemplate implements ProductContract


{
public Name:string = '';
public Price:number = 0;
public Qty: number = 0;
public abstract Total(): number;
public abstract Print(): void;
}

5. components
ProductComponent.ts
import { ProductTemplate } from "../templates/ProductTemplate";

export class ProductComponent extends ProductTemplate


{
Name = 'Samsung TV';
Price = 46000.55;
Qty = 2;
Total() {
return this.Qty * this.Price;
}
Print() {

console.log(`Name=${this.Name}\nPrice=${this.Price}\nQty=${this.Qt
y}\nTotal=${this.Total()}`);
}
}

6. Create a new folder "app"


7. Add a new file
Index.ts

import { ProductComponent } from


"../library/components/ProductComponent";

let tv = new ProductComponent();


tv.Print();
Generic

- It is used to define typesafe components.


- Typesafe component initially allows any type of data, and once
it knows the data type it can restrict to specific.
- You can make a property, method or class as generic.

Syntax:
Method<Type>(Param:Type) : Type
{
}
Method<string>(Param:string): string;
Method<number>(Param:number):number;

- Generic types will not allow operations on value directly as


their data type is unknown. You have to handle using functions.

Add<T>(a:T, b:T):T
{
return a + b; // invalid
return sum(a,b); // valid
}

Ex: Generic Method

function Sum(a:any,b:any) {
return a + b;
}
class Demo
{
public Add<T>(a:T, b:T):T{
return Sum(a,b);
}
}
let obj = new Demo();
console.log(obj.Add<string>("Tom", "Hanks"));
console.log(obj.Add<number>(20,50));

FAQ: Can we have user defined data type as Generic?


Ans: Yes. You can design a contract or class and use as type.

FAQ: What is the difference between contract as type or class


as type?
Ans: Contract is used for rules only.
Class is used for rules and data.

Syntax:
Method<T>(param:T)
{
}
Method<Contract>(param:Contract);
Method<Class>(param:Class);

Ex:
interface IOracle
{
UserName:string;
Password:string;
Database:string;
}
interface IMySql
{
host:string;
user:string;
password:string;
database:string;
}
interface IMongoDB
{
url:string;
}
class SqlServer {
UserId:string = 'Server';
Password:string = '12345'
}

class Database
{
public Connection<T>(connectionString:T){
for(var property in connectionString) {
console.log(`${property} :
${connectionString[property]}`);
}
}
}

console.log(`---------Connection to Oracle---------`);
let oracle = new Database();
oracle.Connection<IOracle>({UserName:'scott',
Password:'tiger', Database:'empdb'});

console.log(`---------Connection to MySql----------`);
let mysql = new Database();
mysql.Connection<IMySql>({host:'localhost', user:'root',
password:'1234', database:'productsdb'});

console.log(`---------Connection to MongoDB---------`);
let mongo = new Database();
mongo.Connection<IMongoDB>({url:'mognodb://127.0.0.1:2701
7'});

console.log(`---------Connection to SqlServer-----`);

let sqlserver = new Database();


let obj = new SqlServer();
sqlserver.Connection<SqlServer>({UserId:obj.UserId,
Password:obj.Password});

FAQ: Can we have Generic array type?


Ans: Yes. Generic can handle any type.

Syntax:
Method<T>(param:T) { }

Method<IProduct[]>([]);

FAQ: Why we need a class a Generic?


Ans: To configure all members in class as generic.
Syntax:
class Name<T>
{
Property:T;
Method():T { }
}

FAQ: Can we define a Generic Contructor?


Ans : No. TypeScript class configures default Generic
constructor.

Ex:

class Factory<T>
{
public FirstName:T|undefined;
public LastName:T|undefined;
}

let StringFactory = new Factory<string>();


StringFactory.FirstName = '';
StringFactory.LastName = '';

let numberFactory = new Factory<number>();


numberFactory.FirstName = 0;

Enums
[Enumeration]
- Enum is a collection of constants.
- It is a key value collection of constants.
- Enum can have collection of number, string and expression
constants.
- A constant is used to initialize values, constant values will not
allow assigning of values.

Syntax:
enum Name
{

- If enum defines numeric constants then they can have auto


implementation for values that fall between a range.

- Numeric constant will increment by one with it pervious value


and implements.

Syntax:
enum Name
{
A = 10,
B
}
Name.B // 11

- The numeric constant in enum starts with 0.

Syntax:
enum Name
{
A, // 0
B=10
}

Ex:
enum StatusCode
{
Method,
NotFound = 404,
OK = 200,
Unauthorized,
}

console.log("Method=" + StatusCode.Method); // 0
console.log("Unauthorized=" + StatusCode.Unauthorized); //
201

- Enum can have string constants.


- But string constants can't have auto implementation.
- They must be initialized with value.

Ex:
enum Route
{
Electronics, // 0
Home = 'http://localhost/app/home HYPERLINK
"http://localhost/app/home&"& HYPERLINK
"http://localhost/app/home&"#39;,
Contact = 'http://127.0.0.1/app/contact?address HYPERLINK
"http://127.0.0.1/app/contact?address&"& HYPERLINK
"http://127.0.0.1/app/contact?address&"#39;,
Fashion = 200
}
console.log(Route.Home);

- Enum can't implement a value if there is no numeric constant


defined at previous level.

Syntax:
enum Name
{
A = 'string',
B // invalid
}
- Enum can have collection of expressions, but only the
expressions that return a number or string.
- Boolean expressions are not allowed in Enum.

FAQ: Which operator is not supported in enum expression?


Ans : The operator that returns boolean value.
> < >= <= == !== === etc..

Ex:
enum Calculate {
A = 10,
B = 20,
C = A + B,
D
}
console.log(`D=${Calculate.D}`);

FAQ: What is reverse mapping of Enum?


Ans: It is a technique of accessing the Enum reference name
using its value.

Syntax:
let name = EnumName[value];

FAQ: How to access value of enum?


Ans : By using Enum reference name

Ex:
enum StatusCode
{
NotFound = 404,
}
let ErrorCode = StatusCode[StatusCode.NotFound];
console.log(`Error Reference: ${ErrorCode}`);
console.log(`Error Code: ${StatusCode.NotFound}`);
- We can also use enum as a type.

Syntax:
enum HttpVerbs
{
GET = 'Fetch Data',
POST = 'Submit Data',
PUT = 'Modify Data'
}
let obj = 'GET' as HttpVerbs;
obj:HttpVerbs;

FAQ: What is the purpose of enum as Type?


Ans: You can declared readonly types.
Namespace
• Namespace is a collection of related type of sub namespaces
and classes.
• You can configure a library under namespace, which contains
set of contracts, templates and components that you can
import into any application.
• The Namespace is defined as a container in which the
components must be marked with “export”.

Ex:
• Add a new folder
Project
1. Add following folders into project folder
- Contracts
- Templates
- Services
- App
2. Add following file into contracts
“ProductContract.ts”

namespace Project
{
export namespace Contracts
{
export interface IProduct
{
Name:string;
Price:number;
Qty:number;
Total():number;
Print():void;
}
}
}

1. Add file into Templates folder


“ProductTemplate.ts”
///<reference path="../Contracts/ProductContract.ts" />

import contracts = Project.Contracts;


namespace Project
{
export namespace Templates
{
export abstract class ProductTemplate implements
contracts.IProduct
{
public Name:string;
public Price:number;
public Qty:number;
public Total():number {
return this.Qty * this.Price;
}
abstract Print():void;
}
}
}

1. Add file into Services folder


“ProductService.ts”
///<reference path="../Templates/ProductTemplate.ts" />

import templates = Project.Templates;

namespace Project
{
export namespace Services
{
export class Product extends templates.ProductTemplate
{
public Name:string = '';
public Price:number = 0;
public Qty:number = 1;
public Total():number {
return this.Qty * this.Price;
}
public Print():void {
console.log(`Name=${this.Name}\nPrice=${this.Price}
\nQty=${this.Qty}\nTotal=${this.Total()}`);
}
}
}
}

1. Add File into APP folder

MyApp.ts

///<reference path="../Services/ProductService.ts" />

import services = Project.Services;

let tv = new services.Product();


tv.Name = "Samsung TV";
tv.Price = 34000.44;
tv.Qty = 2;
tv.Print();

Compile
> tsc --outFile myapp.js myapp.ts

What is Dependency Injection?


- It is a Software Design pattern that specifies how an object
gets hold of its dependencies and injects them into component.
- It deals to 2 types of approaches
a) Single Call
b) Single Ton
- Single Call
It creates an object for every request.
Object is individual for every types of component.
Lot of object will create overhead.
It is good to handle discreet operations.
Component use single call for Factories.
What is a Factory?
- In software framework factory is a set of values and functions.

- Single Ton
It is a software design pattern where object is created for
first request and same object is used for all other requests.

It is good for handling continous operations.


Component use single ton for services.

What is a service?
- It is a predefined bussiness logic which is injected into
application to handle specific operation
- Service is a set of factories.
- Service depends on 2 components
a) Provider
b) Injector
- Provider is responsible for locating service in memory.
- Injector is responsible for injecting service into component.

Note: TypeScript allows to configure DI.


It implement DI and use you need a framework with
provider and
injector.

FAQ: Why you are injecting a service into constructor?


Ans: To Implement single ton.

FAQ: Why you configured as Private?


Ans : It defines accessiblity across the class. [with in the class]

Ex:
1. Add services folder and a new file
"DataService.ts"
export class DataService
{
public GetProducts(){
return [
{Name: 'TV', Price:56000.44},
{Name: 'Mobile', Price: 12000.44}
];
}
public GetCategories(){
return [
'Electronics', 'Footwear', 'Fashion'
];
}
}

2. Add a new folder components with file


ProductComponent.ts

import { DataService } from "../services/DataService";


export class ProductComponent
{
constructor(private data:DataService){

}
public PrintProducts(){
console.log(`----Products List------`);
for(var product of this.data.GetProducts()) {
console.log(`${product.Name} - ${product.Price}`);
}
}
public PrintCategories(){
console.log(`----Categories List-----`);
for(var category of this.data.GetCategories()) {
console.log(category);
}
}
}

Summary:
- Single Call
- Single Ton
- Factory
- Service
- Provider
- Injector

Angular
- Angular is a developers platform.
- A developers platform provides end to end solution for
developer i.e from building to deploying.
- Angular is alternative for Angular.js
- Angular is cross platform, open source framework suitable for
building SPA.
- Angular is mantained by Google and a large community of
developers and organizations.
- Angular started with 2.0 version
- Angular latest is 13.2.2 [stable]
- Angular Versions upto 12 LTS previous versions no-longer
supported.

Features of Angular
1. Developer platform

2. Modular Library
- Application specific framework.
- Faster
- Light weight
- Suitable for low bandwidth devices

3. Differential Loading
- Reduces the compatibility issues
- Loads legacy library for legacy browsers
and loads modern library for modern browsers

4. Asynchronous
- Implicitly uses Ajax for various interactions
- Improves the perfomance of application.

5. It uses AOT compiling techniques [Angular 9+]


[JavaScript uses JIT] Just-in-Time
- Ahead-of-Time

6. Material Library for Effective UI

Setup Environment for Angular:


1. Download and Install Node.js for Package Manager : NPM
2. Download and Install TypeScript
C:\> npm install -g typescript

3. Download and Install Visual Studio Code Editor

4. Download and Install Angular CLI


[CLI is a command line tool used for creating and managing
angular applications]

C:\>npm install @angular/cli -g


C:\>ng --version

Update from older version to latest


==========================

1. un-Install the existing version

C:\>npm uninstall -g @angular/cli

2. Clear Cache

C:\>npm cache verify

3. Install Latest version

C:\>npm install -g @angular/cli

Note: For any specific angular version

C:\>npm install -g @angular/cli@11.0.1

angular.io - version numbers

Create Angular Workspace:


-Workspace provides a platform for handling multiple projects.
-It provides a global library or repository for projects.

1. Open any of your PC locations in command prompt

2. Run the following CLI command

D:\>ng new my-angular-workspace --createApplication=false

3. Open workspace in your VS code editor

File System in Workspace:


1. tsconfig.json : It configures the rules for typescript.
It also defines the environment for typescript
in
angular application.

2. package.json : It comprises of meta data.

3. package-lock.json : It comprises of meta data about every


dependency
installed for project.

4. angular.json : It configures the initial environment for


projects
created in workspace.

- what styles they have to use?


- what script they need to implement?
- which testing framework to use? etc..

5. .gitignore : It comprises of configuration required for


publishing on GIT.

6. .editorconfig : It comprises of rules for editor used by


developers.

www.editorconfig.org

7. node_modules : It comprises of all library files installed


through
NPM.

8. .vscode : It is related to editor to keep migration and


upgrade information.

Create a new application and add to workspace:


====================================
1. Open workspace location in "Terminal"

D:\my-angular-workspace>

2. Run the following CLI command

> ng generate application shopping

3. It will walk through few set of questions

? Would you like to add Angular routing? (y/N) n

? Which stylesheet format would you like to use? CSS


[select with arrow]
[Sass, Less]

4. This will add "Projects" folder into workspace, which contains


your project => "Shopping"

5. Start angular project

D:\my-angular-workspace> ng serve --project=shopping


Project runs on : http://localhost:4200

6. Open any browser and request the URL

http://localhost:4200
- Install Angular
> npm install @angular/cli -g

- Create Workspace

> ng new workspaceName --createApplication=false

- Create Application

> ng generate application appName

- To start application

> ng serve --project=appName

- Request from browser

http://localhost:4200

Angular Application Flow


===================
1. You compile anuglar application
2. "app.module.ts" identifies all the library required for angular
application and injects into memory.
3. Babel uses AOT mechanism and converts that static DOM
into dynamic DOM.
4. The process of converting static DOM into dynamic DOM is
known as "bootstrapping".

Angular Project File System


=====================
1. src : It comprises of all project resources.
2. browserslistrc : It comprises of information about
supported
browser.
[Angular 13 removed support for IE]

3. karma.conf.js : It comprises of configuration for testing


framework used in angular.

[Angular is supported with Jasmine - Karma]

4. tsconfig.app.json : It defines the rules for typescript.

5. tsconfig.spec.json : 'spec' refers to testing file.

Project Resources [SRC]


1. app : It comprises of application resources like
- modules
- components
- services
- pipes etc..

2. assets : It comprises of static resources like


- images
- text documents
- pdf, word, audio , video etc..

3. environments : It contains the files required for


configuring
project environment from development to
production.

4. favicon.ico : It is the favorite icon for website.

5. index.html : It is the startup page

6. main.ts : Entry point, from here your application


starts compiling, processing.

7. polyfills.ts : It handles differential loading


It loads library according to browser.

8. styles.css : It comprises of global styles.


Styles used for all components.

9. test.ts : It is used to start testing of application.

Resources of "app"
===============
1. Angular Framework comprises
- Modules
- Components
- Services
- Factories
- Templates
- Pipes
- Routing
- State Management [Client Side]

Module : Module comprises of set of factories,


services
components, pipes etc..

Factory : Factory comprises of related type of values


and functions.

Service : Service comprises of related type of


factories.

Template : It comprises of a layout rendered into


application

Pipe : It is used for transforming data.

Routing : It is a technique used for configuring


navigation is SPA.

State : It is a technique used to store and manage


data across requests.

Angular Components
=================
- Components are building blocks for Angular Application.
- Application is built by using components.
- A component comprises of
a) Presentation
b) Styles
c) Functionality

- Presentation is defined by using HTML.


- Styles are defined by using CSS.
- Functionality is defined by using TypeScript.
- Components can be added into project by using
a) Manual Apporach
b) CLI Commands

Manually Adding Components


=======================
1. Designing components for Angular Application includes 2
techniques
a) Inline Documentation
b) Code Behind

2. Inline Documentation comprises only one file, which contains


all
3 requirements.
a) Presentation
b) Styles
c) Logic

Inline Documentation Technique for Component


====================================
- In this technique presentation, styles and logic everything kept
is one file.
- It reduces the number of requests for component.
- It improves the page load time.

Issues
- Hard to test
- Separation concerns
- Hard to Extend

When to use?
-If you need a component with stable functionality and design
without regular extensions then go with inline technique.

Designing Component
=================
1. Technically component is designed in a typescript file.
2. Component is a class.

export class HomeComponent


{
}

3. You have to tell the compiler that HomeComponent class is a


component.
It is defined by using "@Component()" directive

FAQ: What is a directive?


Ans: Directive comprises of meta data, which tell the compiler
about the current component.

4. @Component() directive is defined in "Component" base


class of "@angular/core" library.

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

@Component() export class ClassName { }

5. @Component() directive requires meta data, which is defined


as an object with properties and values.

6. Every component meta data requires 3 basic properties

a) selector
b) template
c) styles

selector : It defines the name used to access any


component.
Syntax:
selector : 'app-home'

template : It defines the markup to render.

Syntax:
template: `<markup> {{ expression }}</markup>`

styles : It defines the collection of styles. It is a string array.

Syntax:
styles: ['selector{attribute:value}']

Note: Components added manually are not registered into


application
module, hence it can't load your component.

You have to manually register your component in


application
module "app.module.ts"

@NgModule( {
declarations : [ ComponentName ]
})

7. You have to set your component as startup component

@NgModule({
bootstrap: [ ComponentName ]
})
8. Go to Index.html and use the selector to render component
in body section

<body>
<app-home> </app-home>
</body>

Ex:
1. Add a new folder by name "components" into "app" folder

2. Add a new file into components


"home.component.ts"

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

@Component({
selector: 'app-home',
template: `
<h2>{{title}}</h2>
<p>Online Shopping Application</p>
`,
styles:['h2{text-align:center; background-color:tomato;
color:white}']
})
export class HomeComponent
{
title:string = 'Shopping Home';
}

3. Go to "app.module.ts"

import { HomeComponent } from


'./components/home.component';
declarations: [
HomeComponent
],

bootstrap: [HomeComponent]

4. Go to Index.html

<body>
<app-home> </app-home>
</body>

Components Code Behind, CLI Commands and Multiple


Components

Angular Components
- Manually Add component using Inline Technique
- Manually Add component using Code Behind Technique

* Code Behind Technique allows clean separation of styles,


markup and functionality.
* Every component comprises of 4 files
a) .html Presentation
b) .css Styles
c) .ts Functionality
d) .spec.ts Unit Test
* Easy to extend
* Loosely coupled
* Easy to test
* If you are designing a component with regular extensions
then better use code behind technique.

Ex:
1. Goto "app/components" folder
2. Add a new folder "register"
3. Add the following files
register.component.ts
register.component.html
register.component.css

Note: The meta data for @Component() directive comprises of


following attributes in code behind technique.

templateUrl: './html_file_path'
styleUrls: ['./css_file_path']
selector : 'app-component'

register.component.ts
-----------------------------
import { Component } from "@angular/core";

@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent
{
title:string = 'Register User';
}

register.component.html
--------------------------------
<div id="container">
<form>
<h3>{{title}}</h3>
<dl>
<dt>User Name</dt>
<dd><input type="text"></dd>
<dt>Password</dt>
<dd><input type="password"></dd>
<dt>Email</dt>
<dd><input type="email"></dd>
</dl>
<button>Register</button>
</form>
</div>

register.component.css
-------------------------------
#container{
display: flex;
justify-content: center;
align-items: center;
height: 400px;
}
form {
padding: 20px;
border:2px solid gray;
border-radius: 20px;
}

4. import and register in "app.module.ts"


5. set in bootstrap
6. set in index.html

<app-register> </app-register>

Enable Bootstrap for Angular Project


============================

- Download and Install following libraries in project

> npm install bootstrap --save


> npm install bootstrap-icons --save
- Set Bootstrap library as default for your project
- Go to "src/styles.css" file
- Import the CSS file from "node_modules"

@import '../../../node_modules/bootstrap/dist/css/bootstrap.cs
s';
@import '../../../node_modules/bootstrap-icons/font/bootstrap-
icons.css';

- Go to "register.component.html"

<div id="container">
<form>
<h3><span class="bi bi-person-fill"></span> {{title}}</h3>
<dl>
<dt>User Name</dt>
<dd><input type="text" class="form-control"></dd>
<dt>Password</dt>
<dd><input type="password" class="form-
control"></dd>
<dt>Email</dt>
<dd><input type="email" class="form-control"></dd>
</dl>
<button class="btn btn-primary w-100">Register</button>
</form>
</div>

Adding component using CLI commands


===============================
- CLI commands use scaffolding. [Ruby]
- Scaffolding is a technique of generating logic and
presentation according to the developer requirements.
- You have
a) Client Side Scaffolding
b) Server Side Scaffolding
- Angular CLI using client side scaffolding

Command Description
----------------------------------------------------------------------------------
------
ng generate component name It generates a new
component with
code behind technique.
(or) .html
.css
ng g c name .ts
.spec.ts
It registers component in
AppModule.

--dry-run It is a flag used to preview the


command result without
executing
the command.

--skip-tests It will not generate test file.

--inline-style It will not generate css file

--inline-template It will not generate html file

Ex:
> ng generate component electronics --skip-tests --inline-
style --inline-template

Multiple Components:
1. Add Netflix folder in "app"

2. Generate Components
D:\my-angular-workspace\projects\shopping\src\app\netflix>ng
g c netflix-header --skip-tests

D:\my-angular-workspace\projects\shopping\src\app\netflix>ng
g c netflix-main --skip-tests

D:\my-angular-workspace\projects\shopping\src\app\netflix>ng
g c netflix-register --skip-tests

D:\my-angular-workspace\projects\shopping\src\app\netflix>ng
g c netflix-index --skip-tests

3. netflix-index.component.html

<div class="container-fluid" id="background">


<div id="box">
<div class="mt-4">
<app-netflix-header></app-netflix-header>
<div class="d-flex justify-content-center align-items-
center" style="height:300px">
<app-netflix-main></app-netflix-main>
</div>
</div>
</div>
</div>

.css
#background {
background-image: url("/assets/netflixback.png");
height: 768px;
}
#box {
margin: -30px;
background-color: rgba(0,0,0,0.5);
height: 768px;
}

4. netflix-header.component.html

<div class="container-fluid mt-3">


<div class="m-3 p-3 d-flex justify-content-between">
<span class="brand">NETFLIX</span>
<span>
<select class="me-3">
<option>Language</option>
<option>English</option>
</select>
<button class="btn btn-danger">Signin</button>
</span>
</div>
</div>

.css
.brand {
font-size: 30px;
color:red;
}

5. netflix-main.component.html

<div>
<h1>Unlimited movies, TV shows and more.
</h1>
<h2> Watch anywhere. Cancel anytime.</h2>
<div class="mt-4">
<app-netflix-register></app-netflix-register>
</div>
<div class="mt-4">
<app-netflix-register></app-netflix-register>
</div>
</div>

.css
div {
color:white;
text-align: center;
}

6. netflix-register.component.html

<div>
<p>Ready to watch? Enter your email to create or restart
your membership.</p>
<div class="input-group input-group-lg">
<input type="email" placeholder="Your email address"
class="form-control">
<button class="btn btn-danger">
Get Started <span class="bi bi-chevron-right"></span>
</button>
</div>
</div>
Data Binding in Angular
==================
- Data Binding is a technique that allows the data to bind with
UI.
- It is a process of accessing data from source and presenting
in the UI, identifying the changes in UI and updating back to
data source.
- JavaScript and jQuery depends on lot of DOM manipulations
and Events.
- Angular can handle data binding by using frameworks like
a) MVC
b) MVVM
- Framework can bind and update without using explicit
events.
What is MVC?
- MVC is Model View Controller
- Trygve introduced the concept of MVC in early 1970's.
- First formulated with a language called "Small Talk".
- Code separation and reusability concerns.
- MVC is known to various technologies
Java Spring
PHP CakePHP, Code Igniter
Python Django, Flask, Grock
Ruby Ruby on Rails
.NET ASP.NET MVC
JavaScript SPINE, Angular

Model
=====
- It represents the data we are working with.
- It comprises of data specific logic and queries.
- It is an abstraction of data in memory.
- It may contain data validations.

View
====
- It represents the User Interface.
- It describes the presentation.
- It is under the control of view engine, which is now removed
Angular 13.
- View Engine responsibility is to render the output.
- Angular upto 13 version used a view engine called "Ivy".
- Babel manages rendering from Angular 13.
SPARK
NAHML
Django
Razor
ASPX
Controller
========
- It defines application specific logic.
- It is the core MVC component.
- It handle overall application flow.
- It can fetch data from source and present in UI, identify
changes in UI and update back to Model.

Angular supports 2 types of Data Binding technique using


MVC
1. One Way Binding
2. Two Way Binding

One Way Binding:


- It is the process of accessing data from model and update to
UI.
- It can be done by using
a) Interpolation
b) Property Binding
c) Attribue Binding

Interpolation:
- It uses a data binding expression. "{{ }}"
- It will not bind to any HTML element, It is just used as literal.
- Literal will not be embedded into element.
- As literal it can't handle certain properies of HTML element.

Syntax:
product:any = {
Name: 'Samsung TV'
}

<dd> {{ product.Name }} </dd>


<input type="text" value={{product.Name}}>
- It is not good for binding a dynamic value to any property of
HTML element.

product:any = {
Stock: true
}

<input type="checkbox" checked={{product.Stock}}>


// not good

Property Binding
=============
- You can access any HTML element property using property
binding entity "[ ]" and bind the dynamic value.

- It allows to bind the data and update.

Syntax:
product:any = {
Stock : true
}

<input type="checkbox" [checked]="product.Stock">

- Every HTML element attributes are not available as


properties, Hence you can use property binding for certain
attributes.

Syntax:
width:number = 400;
height:number = 100;

<table [width]="width" [height]="height">

Note: Table element is not having height as property, It is only


available as attribute.
[height]="height" // invalid

FAQ: What is difference between attribute and property?


Ans: Attributes are immutable, can't change according to
state and
situation.
Properties are mutable, can change according to state
and
situation.

<img src="" class="">

img.src;
img.className

<table height="400">

table.style.height="100px";

Attribute Binding
============
- It allows to bind any dynamic value to element attribute.
- The attributes are defined by using "attr" prefix.

[attr.AttributeName] = "dynamicValue"

<table [attr.height]="tableHeight">

Ex:
databinding.component.ts

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

@Component({
selector: 'app-databinding',
templateUrl: './databinding.component.html',
styleUrls: ['./databinding.component.css']
})
export class DatabindingComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}
product:any = {
Name: 'Samsung TV',
Price: 56000.55,
Stock: false
}
tableHeight:number = 100;
tableWidth:number = 500;
tableBorder:number = 1;
}

databinding.component.html

<div class="container-fluid">
<h2>Table</h2>
<table [border]="tableBorder" [width]="tableWidth"
[attr.height]="tableHeight">
<tr>
<td>{{product.Name}}</td>
</tr>
</table>
<h2>Product Details</h2>
<dl>
<dt>Name</dt>
<dd>{{product.Name}}</dd>
<dt>Price</dt>
<dd>{{product.Price}}</dd>
<dt>Stock</dt>
<dd><input type="checkbox" [checked]="product.Stock" >
Available</dd>
</dl>
</div>

One Way Binding - Can't update the UI changes into Data


Source

Two Way Binding:


- It is a technique of accessing data from source and binding
to UI then identifying the changes in UI and updating back to
data source.

- JavaScript, jQuery requires "event binding" to handle two


way binding.

- Angular uses "Model" to handle two way binding.


- Model defined "Single-source-of-truth".
- It comprises of information about data before and after
change.
- Angular uses "ngModel" directive that configures
[] - Property Binding
() - Event Binding
- ngModel is defined to bind with the default property of
element according to element type and data type.

[ngModel] => Textbox => Value


[ngModel] => CheckBox => Checked

- ngModel is defines to bind with the default event of element.

(ngModel) => Textbox => Keyup


(ngModel) => Select => Change

- ngModel uses both property and event binding to handle two


way binding
[(ngModel)] = "dynamicValue"

- ngModel is a member of "FormsModule" defined in


"@angular/forms"

Ex:
1. Go to "app.module.ts"

import { FormsModule } from '@angular/forms';

imports: [
FormsModule
]

2. data.component.ts

productName:string = 'Samsung TV';


Stock:boolean = true;
City:string = 'Delhi';

3. data.component.html

<div class="container-fluid">
<h2>Product Details</h2>
<dl>
<dt>Name</dt>
<dd>
<input type="text" [(ngModel)]="productName">
</dd>
<dt>Stock</dt>
<dd>
<input type="checkbox" [(ngModel)]="Stock" >
Available
</dd>
<dt>Shipped To</dt>
<dd>
<select [(ngModel)]="City">
<option>Hyd</option>
<option>Mumbai</option>
<option>Delhi</option>
</select>
</dd>
</dl>
Product Name : {{productName}} <br>
Stock : {{(Stock==true)?'Available':'Out of Stock'}} <br>
Shipped To : {{City}}
</div>
MVVM
[Model View - View Model]
- Model represents data.
- View represents UI.
- View Model represents the data logic at UI.
- It eliminates the interaction with controller in data binding.
- It is good for inline techniques.
- Extensibility and speration issues.
- Heavy on UI.
- NgModel is used for binding data and updating at view level.
- NgModel requires a model reference for every element.

Syntax:
<input
type="text" name="Price" ngModel #Price="ngModel">

- Every model reference is an object that comprises of various


details about the element.

value It returns the value or state


pristine
dirty
valid
invalid
touched
untouched

Ex:
databinding.component.ts
// no changes requires

databinding.component.html

<div class="container-fluid">
<div class="row">
<div class="col-3">
<h2>Register Product</h2>
<dl>
<dt>Name</dt>
<dd><input type="text" name="Name" ngModel
#Name="ngModel" class="form-control"></dd>
<dt>Price</dt>
<dd><input type="text" name="Price" ngModel
#Price="ngModel" class="form-control"></dd>
<dt>Stock</dt>
<dd class="form-switch">
<input class="form-check-input" ngModel
#Stock="ngModel" name="Stock" type="checkbox"> Available
</dd>
<dt>Shipped To</dt>
<dd>
<select name="City" ngModel #City="ngModel"
class="form-select">
<option>Delhi</option>
<option>Hyd</option>
</select>
</dd>
</dl>
</div>
<div class="col-9">
<h2>Product Details</h2>
<dl>
<dt>Name</dt>
<dd>{{Name.value}}</dd>
<dt>Price</dt>
<dd>{{Price.value}}</dd>
<dt>Stock</dt>
<dd>{{(Stock.value==true)?"Available":"Out of
Stock"}}</dd>
<dt>Shipped To</dt>
<dd>{{City.value}}</dd>
</dl>
<h3>Name object Properties</h3>
Pristine : {{Name.pristine}} <br>
Dirty : {{Name.dirty}} <br>
Valid : {{Name.valid}} <br>
Invalid : {{Name.invalid}} <br>
Touched : {{Name.touched}} <br>
Untouched : {{Name.untouched}}
</div>
</div>
</div>

Fetching Data from API and Binding to View using


JavaScript "fetch()"

fetch() JavaScript
$.ajax() jQuery
$.getJSON() jQuery
HttpClient Angular

Syntax:
fetch('api_url')
.then(function(response){
return response.json();
})
.then(function(data){
// use data
})

Syntax: Arrow

fetch('api_url')
.then(response=>response.json())
.then(data=> { // use data } )

Ex:
databinding.component.ts

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

@Component({
selector: 'app-databinding',
templateUrl: './databinding.component.html',
styleUrls: ['./databinding.component.css']
})

export class DatabindingComponent implements OnInit {

product:any = {};
productId:number = 5;

constructor() { }

ngOnInit(): void {
fetch(`http://fakestoreapi.com/products/${this.productId}`)
.then(response=> response.json())
.then(data=> {
this.product = data;
})
}

databinding.component.html

<div class="container-fluid">
<h2>Product Details</h2>
<div class="mb-2 w-50">
<input type="range" [(ngModel)]="productId" min="1"
value="1" max="20" class="form-range">
</div>
<div class="card m-3 p-3 w-50">
<img [src]="product.image" height="200" class="card-img-
top">
<div class="card-header" style="height: 140px;">
<h3>{{product.title}}</h3>
<p>{{product.price}}</p>
</div>
<div class="card-body">
<p>{{product.description}}</p>
</div>
<div class="card-footer">
<span class="bi bi-star-fill text-success"></span>
{{product.rating.rate}}
<span class="text-light">[product.rating.count]</span>
</div>
</div>
</div>
Angular Directives
===============
- Directive is a function that can
a) return markup
b) extend markup
c) make markup more interactive
- All directives will not have the same behaviour.
- Directive can be used as
a) Element
b) Attribute

<app-login> Element
ngModel Attribute

- Directive is used as element when it have to return markup.


- Directive is used as attribute when it have to extend markup or
make markup more interactive.
- Angular provides built-in directives and also allows to create
custom directives.
- Angular built-in directives are classified into following
categories

a) Structrual Directives
b) Attribute Directives
c) Component Directives

Structural Directives:
- A structural directive can control DOM structure.
- It can
a) Add Elements
b) Remove Elements
c) Repeat Elements
- Angular Structural directives are
ngIf
ngSwitch
ngFor

NgIf
=====
- It is a structural directive used to add or remove any element
from DOM.
- It uses a boolean value "true or false".

Note:
- Structural directives are added to element by using "*"
<div *ngIf="" >

- Element element can have only one structural directive.

<div *ngFor="" *ngIf=""> // invalid

- ngIf can remove DOM element when set to false.


- ngIf can add DOM element when set to true.
- ngIf can use a boolean expression that can dynamically
change boolean value.

Syntax:
<dd *ngIf="false">
<img [src]="" width="" height="">
</dd>

Ex:
ifdemo.component.ts

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

@Component({
selector: 'app-ifdemo',
templateUrl: './ifdemo.component.html',
styleUrls: ['./ifdemo.component.css']
})
export class IfdemoComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}
product:any = {
Name: 'Nike Casuals',
Price: 6000.44,
Preview: 'assets/shoe.jpg'
}

ifdemo.component.html

<div class="container-fluid">
<h2>Product Details</h2>
<dl>
<dt>Name</dt>
<dd>{{product.Name}}</dd>
<dt>Price</dt>
<dd>{{product.Price}}</dd>
<dt class="form-switch">
<input name="preview" ngModel #preview="ngModel"
class="form-check-input" type="checkbox">
{{(preview.value)?'Hide Preview':'Show Preview'}}
</dt>
<dd *ngIf="preview.value">
<img [src]="product.Preview" width="200" height="200">
</dd>
</dl>
</div>
NgIf with Alternative Code Blocks
=========================
- An alternative code block is used to display content when
condition evaluates to false.
- NgIf can use alternative block, which is reffered as "then"
block
- NgIf can use "then" block with "else" block to identify the
condition and return a suitable presentation.

Syntax:
<div *ngIf="booleanExpression; then thenBlock else
elseBlock">
</div>

- Dynamic rendering of contents can't be handled using HTML


containers, Angular provides dynamic container

<ng-template>
... your markup or content....
</ng-template>

- Every dynamic template must have a reference

<ng-template #name>
</ng-template>

- NgIf can access the template by using "then" reference or


"else"

<div *ngIf="true then name">


</div>
NgIF with Alternative Block
------------------------------------
- You can configure NgIf with "then" and "else" block.
- "then" specifies the template to render when condition is true.
- "else" specifies the template to render when condition is false.

Syntax:

<div *ngIf="condition; then thenBlock; else elseBlock">


</div>
<ng-template #thenBlock> </ng-template>
<ng-template #elseBlock> </ng-template>

Ex:
ifdemo.component.ts

isVisible:boolean = true;

ifdemo.component.html

<div class="container-fluid">
<div *ngIf="isVisible; then thenBlock; else elseBlock"></div>
<ng-template #thenBlock>
Template to display when condition true
</ng-template>
<ng-template #elseBlock>
Template to display when condition false
</ng-template>
</div>

Ex:
ifdemo.component.ts

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

@Component({
selector: 'app-ifdemo',
templateUrl: './ifdemo.component.html',
styleUrls: ['./ifdemo.component.css']
})
export class IfdemoComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}
product:any = {
Name: 'Nike Causals',
Preview: 'assets/shoe.jpg',
Description: 'something about nike casuals'
}
btnText:string = 'Description';
togglePreview:boolean = true;

PreviewClick(){
this.togglePreview = (this.togglePreview==true)?false:true;
this.btnText =
(this.btnText=='Description')?'Preview':'Description';
}
}

ifdemo.component.html

<div class="container-fluid">
<h2>Product Details</h2>
<dl>
<dt>Name</dt>
<dd>{{product.Name}}</dd>
<dt><button (click)="PreviewClick()" class="btn btn-
primary">{{btnText}}</button></dt>
<dd>
<div *ngIf="togglePreview; then preview; else
description"></div>
<ng-template #preview>
<img [src]="product.Preview" width="200"
height="200">
</ng-template>
<ng-template #description>
<p>{{product.Description}}</p>
</ng-template>
</dd>
</dl>
</div>

FAQ: Can we define multiple then blocks in "ngIf"?


Ans: No.

FAQ: How to manage multiple conditions in "ngIf"?


Ans: By implementing "Content Projection".

Content Projection
-------------------------
- Content Projection is a technique where templates are
configured explicitly and rendered into component according to
state and situation.

- It allows to create a template explicitly and render into view.


[UI]

- The process of creating explicit templates and injecting into


View is known as "Content Projection".

- Templates are explicitly created by using "TemplateRef<T>"

Syntax:
thenBlock1 : TemplateRef<any>;
- A "TemplateRef<T>" can handle Markup, Styles, Dynamic
values.

- Injecting into View is managed by a directive "@ViewChild()"

- @ViewChild() can identify template type reference in memory


and render it into the View. [Provider - Injector]

- ViewChild is rendering child templates into View dynamically.

- You have to import "TemplateRef and ViewChild" from


"@angular/core" library.

- ngIf comprises of only one "then" block in condition.

- A single "then" block in condition can map to multiple


templates and render using "Content Projection".

Ex:
ifdemo.component.ts

import { Component, OnInit, TemplateRef, ViewChild } from


'@angular/core';

@Component({
selector: 'app-ifdemo',
templateUrl: './ifdemo.component.html',
styleUrls: ['./ifdemo.component.css']
})
export class IfdemoComponent implements OnInit {

thenBlock:TemplateRef<any>|null = null;
isVisible:boolean = true;
@ViewChild('Block1', {static:true})
Block1:TemplateRef<any>|null = null;
@ViewChild('Block2', {static:true})
Block2:TemplateRef<any>|null = null;

constructor() { }

ngOnInit(): void {
this.thenBlock = this.Block1;
}
SwitchClick(){
this.thenBlock =
(this.thenBlock==this.Block1)?this.Block2:this.Block1;
}
}

ifdemo.component.html

<div class="container-fluid">
<button (click)="SwitchClick()">
Switch Then Block
</button>
<div *ngIf="isVisible; then thenBlock; else elseBlock"></div>
<ng-template #Block1>
Then Block1
</ng-template>
<ng-template #Block2>
Then Block2
</ng-template>
<ng-template #elseBlock>
else block
</ng-template>
</div>
• Ex: Content Projection

ifdemo.component.ts

import { Component, OnInit, TemplateRef, ViewChild } from


'@angular/core';

@Component({
selector: 'app-ifdemo',
templateUrl: './ifdemo.component.html',
styleUrls: ['./ifdemo.component.css']
})
export class IfdemoComponent implements OnInit {

product:any = {};

GetData(id:number) {
fetch(`http://fakestoreapi.com/products/${id}`)
.then(response=>response.json())
.then(data => {
this.product = data;
})
}
count:number = 1;
ButtonText:string = 'Price | Rating';
ToggleTemplate:TemplateRef<any>|null = null;

@ViewChild('DescriptionTemplate', {static: true})


DescriptionTemplate:TemplateRef<any>|null = null;
@ViewChild('RatingTemplate', {static:true})
RatingTemplate:TemplateRef<any>|null = null;

constructor() { }

ngOnInit(): void {
this.GetData(this.count);
this.ToggleTemplate = this.DescriptionTemplate;
}
NextClick(){
this.count++;
this.GetData(this.count);
}
PreviousClick(){
this.count--;
this.GetData(this.count);
}
ToggleDetails(){
this.ToggleTemplate =
(this.ToggleTemplate==this.DescriptionTemplate)?this.RatingT
emplate: this.DescriptionTemplate;
this.ButtonText = (this.ButtonText=='Price |
Rating')?'Description':'Price | Rating';
}

ifdemo.component.html

<div class="container-fluid">
<div class="mt-3 btn-group">
<button (click)="PreviousClick()" class="btn btn-danger">
&laquo; </button>
<button (click)="NextClick()" class="btn btn-warning">
&raquo; </button>
</div>
<div class="card w-25 m-2 p-2">
<img [src]="product.image" height="200" class="card-img-
top">
<div class="card-header" style="height: 170px;">
<h5>{{product.title}}</h5>
</div>
</div>
<div class="details">
<button (click)="ToggleDetails()" class="btn btn-primary">
<span class="bi bi-eye-fill"></span>
{{ButtonText}}
</button>
<div *ngIf="true; then ToggleTemplate"></div>
<ng-template #DescriptionTemplate>
<h2>Product Description</h2>
<p>{{product.description}}</p>
</ng-template>
<ng-template #RatingTemplate>
<h2>Product Price | Rating</h2>
<dl>
<dt>Price</dt>
<dd>{{product.price}}</dd>
<dt>Rating</dt>
<dd>
<span class="bi bi-star-fill text-success"></span>
{{product.rating.rate}} [<span class="text-
dark">{{product.rating.count}}</span>]
</dd>
</dl>
</ng-template>
</div>
</div>

ifdemo.component.css

.details {
position: fixed;
right: 320px;
top: 100px;
width: 400px;
}

FAQ: What is the issue with NgIF?


Ans:Rendering multiple templates requires explicit "Content
Projection".
Creating and adding a template dynamically will delay the
rendering time.

FAQ: What is the solution?


Ans: Better use a "UI" switch that can select and render only
the template that is required.

"NgSwitch" - Structrual Driective


=========================
- NgSwitch can define multiple templates in UI.
- Content Projection not required.
- No need of creating explicit templates.
- NgSwitch can select the template that matches given
condition and renders into UI.
- It will reduce the "Provider" time and improves rendering time.
[Provider time is the time taken to create and locate template
in memory]
- NgSwitch uses
a) ngSwitch
b) ngSwitchCase
c) ngSwitchDefault

Syntax:
<parent-container [ngSwitch]="CaseString">
<child-container *ngSwitchCase=" 'case1' ">
</child-container>
<child-container *ngSwitchDefault>
</child-container>
</parent-container>

- ngSwitchDefault is the container, which is rendered when any


given case string is not matching with the templates defined.

- ngSwitch can directly work on HTML containers.

Ex: SwitchCase - Syntax Demo

switchdemo.component.html

<div class="container-fluid">
<div [ngSwitch]="'case4'">
<div *ngSwitchCase="'case1'">
Container Case-1
</div>
<div *ngSwitchCase="'case2'">
Container Case-2
</div>
<div *ngSwitchCase="'case3'">
Container Case-3
</div>
<div *ngSwitchDefault>
Container Case Default
</div>
</div>
</div>

Ex: Switch Demo

switchdemo.component.ts

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

@Component({
selector: 'app-switchdemo',
templateUrl: './switchdemo.component.html',
styleUrls: ['./switchdemo.component.css']
})
export class SwitchdemoComponent implements OnInit {

product:any = {};
GetData(productid:number) {
fetch(`http://fakestoreapi.com/products/${productid}`)
.then(response=> response.json())
.then(data=> {
this.product = data;
})
}
TemplateToDisplay:string = 'basic';

constructor() { }
ngOnInit(): void {
this.GetData(2);
}

ChangeTemplate(e:any){
this.TemplateToDisplay = e.target.name;
}

switchdemo.component.html

<div class="container-fluid">
<h2>Product Details</h2>
<div class="btn-toolbar bg-danger">
<div class="btn-group">
<button (click)="ChangeTemplate($event)"
name="basic" class="btn btn-danger">Basic Details</button>
<button (click)="ChangeTemplate($event)"
name="preview" class="btn btn-danger">Preview</button>
<button (click)="ChangeTemplate($event)"
name="rating" class="btn btn-danger">Price and
Rating</button>
<button (click)="ChangeTemplate($event)"
name="description" class="btn btn-
danger">Description</button>
</div>
</div>
<div class="mt-3" [ngSwitch]="TemplateToDisplay">
<div *ngSwitchCase="'basic'">
<h3>Product Title</h3>
<p>{{product.title}}</p>
</div>
<div *ngSwitchCase="'preview'">
<h3>Preview</h3>
<img [src]="product.image" width="200" height="200">
</div>
<div *ngSwitchCase="'rating'">
<h3>Price and Rating</h3>
<dl>
<dt>Price</dt>
<dd>{{product.price}}</dd>
<dt>Rating</dt>
<dd>
<span class="bi bi-star-fill text-success"></span>
{{product.rating.rate}} [{{product.rating.count}}]
</dd>
</dl>
</div>
<div *ngSwitchCase="'description'">
<h3>Description</h3>
<p>
{{product.description}}
</p>
</div>
</div>
</div>

Task: Get Data from Nasa API

https://api.nasa.gov/mars-
photos/api/v1/rovers/curiosity/photos?sol=1000 HYPERLINK
"https://api.nasa.gov/mars-
photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=DEM
O_KEY"& HYPERLINK "https://api.nasa.gov/mars-
photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=DEM
O_KEY"api_key=DEMO_KEY

Present
- Image Preview
- Rover Name
- Camera Name
- Date taken
NgFor
======
- It is a repeater, used to repeat any HTML element.
- It can create element dynamically and repeat according to
given iterator.
- It uses an iterator for repeating elements.
- Iterator is a software design pattern used to read elements
from a collection in sequential order.
- NgFor uses "for..of" iterator

for..in : To read all properties from collection


for..of : To read all values from collection

JavaScript:
- It have to create element dynamically
- Set properties to element
- Append element to its parent.

Ex:
<head>
<script>
var categories = ['Electronics', 'Footwear', 'Fashion'];
function bodyload(){
for(var item of categories)
{
var li = document.createElement("li");
li.innerHTML = item;
document.querySelector("ol").appendChild(li);

var option = document.createElement("option");


option.text = item;
option.value = item;
document.querySelector("select").appendChild(optio
n);
}
}
</script>
</head>
<body onload="bodyload()">
<ol>

</ol>
<select>

</select>
</body>

Angular:
- It uses "ngFor" to create element dynamically and repeat
according to iterator.

<element *ngFor="let item of collection"> </element>

Syntax:
collection = [ 'A', 'B', 'C' ];

<ol>
<li *ngFor="let item of collection"> {{ item }} </li>
</ol>

<select>
<option *ngFor="let item of collection" [value]="item">
{{item}}
</option>
</select>

<tbody>
<tr *ngFor="let item of collection">
<td> {{item}} </td>
</tr>
</tbody>
Ex:
fordemo.component.ts

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

@Component({
selector: 'app-fordemo',
templateUrl: './fordemo.component.html',
styleUrls: ['./fordemo.component.css']
})
export class FordemoComponent implements OnInit {

categories:any[] = [];

GetCategories(){
fetch('http://fakestoreapi.com/products/categories
HYPERLINK "http://fakestoreapi.com/products/categories&"&
HYPERLINK
"http://fakestoreapi.com/products/categories&"#39;)
.then(response=> response.json())
.then(data=> {
data.unshift("all")
this.categories = data;
})
}

constructor() { }

ngOnInit(): void {
this.GetCategories();
}

fordemo.component.html
<div class="container-fluid">
<h2>NgFor Demo</h2>
<div class="row">
<div class="col">
<ol>
<li *ngFor="let item of categories">
{{item}}
</li>
</ol>
</div>
<div class="col">
<select class="form-select">
<option *ngFor="let item of categories">
{{item}}
</option>
</select>
</div>
<div class="col">
<div class="p-4" style="height: 80px; border:2px solid
black; overflow: auto;">
<ul class="list-unstyled">
<li *ngFor="let item of categories">
<input type="checkbox"> {{item}}
</li>
</ul>
</div>
</div>
<div class="col">
<table class="table table-hover table-dark">
<thead>
<tr>
<th>Categories</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of categories">
<td>{{item}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

Nested Iterations
==============
- NgFor allows nested approach, where you can define a
repeater within another repeater.

JavaScript Nested Iterations:

<head>
<script>
var data = [
{Category: "Electronics", Products: ["TV", "Mobile"]},
{Category: "Footwear", Products:["Nike Casuals", "Lee
Boot"]}
];
function bodyload(){
for(var item of data)
{
var li = document.createElement("li");
li.innerHTML = item.Category;
document.querySelector("ol").appendChild(li);
for(var product of item.Products)
{
var ul = document.createElement("ul");
var ulLi = document.createElement("li");
ulLi.innerHTML = product;
ul.appendChild(ulLi);
document.querySelector("ol").appendChild(ul);
}
}
}
</script>
</head>
<body onload="bodyload()">
<ol>

</ol>

</body>

Angular Nested Iterations

<parent *ngFor="let item of collection">


<child *ngFor="let child of item.Collection">
</child>
</parent>

Ex:
fordemo.component.ts

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

@Component({
selector: 'app-fordemo',
templateUrl: './fordemo.component.html',
styleUrls: ['./fordemo.component.css']
})
export class FordemoComponent implements OnInit {

data:any[] = [
{Category: "Electronics", Products: ["TV", "Mobile"]},
{Category: "Footwear", Products:["Nike Casuals", "Lee
Boot"]}
];
constructor() { }

ngOnInit(): void {

fordemo.component.html

<div class="container-fluid">
<h2>NgFor Nested Demo</h2>
<div class="row">
<div class="col">
<ol>
<li *ngFor="let item of data">
{{item.Category}}
<ul>
<li *ngFor="let product of item.Products">
{{product}}
</li>
</ul>
</li>
</ol>
</div>
<div class="col">
<select class="form-select">
<optgroup *ngFor="let item of data"
[label]="item.Category">
<option *ngFor="let product of item.Products">
{{product}}
</option>
</optgroup>
</select>
</div>
</div>
</div>

Ex: Nasa API tabular data

fordemo.component.ts

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

@Component({
selector: 'app-fordemo',
templateUrl: './fordemo.component.html',
styleUrls: ['./fordemo.component.css']
})
export class FordemoComponent implements OnInit {

MarsObject:any = {};

GetMarsPhotos(){
fetch('https://api.nasa.gov/mars-
photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=DEM
O_KEY’)
.then(response=> response.json())
.then(data=> {
this.MarsObject = data;
})
}

constructor() { }

ngOnInit(): void {
this.GetMarsPhotos();
}
}

fordemo.component.html

<div class="container-fluid">
<h2>Mars Photos</h2>
<table class="table table-hover">
<thead>
<tr>
<th>Photo Id</th>
<th>Camera Name</th>
<th>Image</th>
<th>Rover Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of MarsObject.photos">
<td>{{item.id}}</td>
<td>{{item.camera.full_name}}</td>
<td>
<img [src]="item.img_src" width="100"
height="100">
</td>
<td>
{{item.rover.name}}
</td>
</tr>
</tbody>
</table>
</div>

Ex: Card Style

fordemo.component.html
<div class="container-fluid">
<h2>Mars Photos</h2>
<div class="d-flex flex-wrap">
<div *ngFor="let item of MarsObject.photos" class="card
m-3 p-2" style="width: 200px;">
<img [src]="item.img_src" height="200" class="card-
img-top">
<div class="card-header">
<h3>{{item.id}}</h3>
</div>
<div class="card-body">
<dl>
<dt>Camera Name</dt>
<dd>{{item.camera.full_name}}</dd>
<dt>Rover Name</dt>
<dd>{{item.rover.name}}</dd>
</dl>
</div>
</div>
</div>
</div>

ngFor properties
- index
- first
- last
- even
- odd
- trackBy
NgFor Properties
==============

Property Type Description


----------------------------------------------------------------------------------
------
index number It returns the repeating element
Index. [starts with 0]

first boolean It returns true if element is the


first
repeating element.

last boolean It returns true if element is the


last
repeating element.

even boolean It returns true if element is at


even
occurance.

odd boolean It returns true if element is at


odd occurance.

trackBy function It identifies the changes in


repeating
index and returns the index.

Syntax:
<li *ngFor="let item of collection; let i=index; let e=even">

Index Property of NgFor


===================
- It returns the index number of repeating element.
- You can manipulate any specific repeating element by using
index.

Ex:
indexdemo.component.ts

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

@Component({
selector: 'app-indexdemo',
templateUrl: './indexdemo.component.html',
styleUrls: ['./indexdemo.component.css']
})
export class IndexdemoComponent implements OnInit {

products:any[] = [];
productName:string = '';
productPrice:number = 0;
product:any = {};

constructor() { }

ngOnInit(): void {
}

RegisterClick(){
this.product = {
Name: this.productName,
Price: this.productPrice
}
this.products.push(this.product);
alert('Product Registered..');
this.productName = '';
this.productPrice = 0;
}
DeleteClick(index:number){
let flag = confirm('Are you sure, want to Delete?');
if(flag==true) {
this.products.splice(index,1);
}
}

indexdemo.component.html

<div class="container-fluid">
<div class="row">
<div class="col-3">
<h2>Register Product</h2>
<dl>
<dt>Name</dt>
<dd><input type="text" [(ngModel)]="productName"
class="form-control"></dd>
<dt>Price</dt>
<dd><input type="text" [(ngModel)]="productPrice"
class="form-control"></dd>
</dl>
<button (click)="RegisterClick()" class="btn btn-primary
w-100">Register</button>
</div>
<div class="col-9">
<h2>Product Details</h2>
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr [class.even-style]="even" [class.odd-style]="odd"
*ngFor="let item of products; let i=index; let even=even; let
odd=odd">
<td>{{item.Name}}</td>
<td>{{item.Price}}</td>
<td>
<button (click)="DeleteClick(i)" class="btn btn-
danger">
<span class="bi bi-trash-fill"></span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

indexdemo.component.css

.even-style
{
background-color: rgb(209, 252, 209);
}
.odd-style {
background-color: rgb(250, 194, 194);
}

NgFor "trackBy" property


====================
- NgFor is a repeater.
- NgFor uses an iterator for repeating elements in collection.
- Iterator executes every time when ngFor is called.
- Iterator executes even when there is no change in collection.
- "trackBy" is a function that tracks the changes in "ngFor" and
iterates only the changed item in collection.
- It saves round trips and improves the performance.

Ex:
trackdemo.component.ts

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

@Component({
selector: 'app-trackdemo',
templateUrl: './trackdemo.component.html',
styleUrls: ['./trackdemo.component.css']
})
export class TrackdemoComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}
products:any[] = [
{Name: 'TV', Price: 46000.55},
{Name: 'Mobile', Price:23000.44},
{Name: 'Nike Casuals', Price: 6300.33}
];

AddNewProduct(){
this.products = [
{Name: 'TV', Price: 46000.55},
{Name: 'Mobile', Price:23000.44},
{Name: 'Nike Casuals', Price: 6300.33},
{Name: 'Watch', Price: 6700.55}
];
alert('Add Clicked');
}
TrackChanges(index:number) {
return index;
}

trackdemo.component.html

<div class="container-fluid">
<button (click)="AddNewProduct()" class="btn btn-
primary">Add New</button>
<div>
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of products;
trackBy:TrackChanges">
<td>{{item.Name}}</td>
<td>{{item.Price}}</td>
</tr>
</tbody>
</table>
</div>
</div>

Ex: Likes Counter

component.ts

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


@Component({
selector: 'app-trackdemo',
templateUrl: './trackdemo.component.html',
styleUrls: ['./trackdemo.component.css']
})
export class TrackdemoComponent implements OnInit {

products:any[] = [
{Name: 'Nike Casuals', Photo: 'assets/shoe.jpg', Likes:0,
Dislikes:0},
{Name: 'Lee Boot', Photo: 'assets/shoe1.jpg', Likes:0,
Dislikes:0}
]
constructor() { }

ngOnInit(): void {
}
LikesClick(item:any){
item.Likes++;
}
DislikesClick(item:any) {
item.Dislikes++;
}

component.html

<div class="container-fluid">
<div class="d-flex flex-wrap m-3">
<div class="card m-2 p-2" *ngFor="let item of products"
style="width: 400px;">
<img [src]="item.Photo" height="200px" class="card-img-
top">
<div class="card-header">
<h3>{{item.Name}}</h3>
</div>
<div class="card-footer btn-group">
<button (click)="LikesClick(item)" class="btn btn-
success">
<span class="bi bi-hand-thumbs-up-fill"></span>
[{{item.Likes}}] Like(s)
</button>
<button (click)="DislikesClick(item)" class="btn btn-
danger">
<span class="bi bi-hand-thumbs-down-fill"></span>
[{{item.Dislikes}}] Dislike(s)
</button>
</div>
</div>
</div>
</div>

Summary:
- ngIf
- ngIF content projection
- ngSwitch
- ngFor

Attribute Directives
===============
- Attributes directive are used to extend HTML.
- They can make HTML more interactive and responsive.
- They will convert a static HTML element into dynamic
element.
- Angular attribute directives are:
a) NgClass
b) NgStyle
c) NgModel

NgClass:
=======
- It is used to define a CSS class dynamically.
- You can change the appearence of element dynamically.

<div [ngClass]=""> </div>

- You can configure CSS class dynamically in 3 ways

a) String Reference Single Class


b) Array Reference Multiple Classes
c) Object Reference Switch between classess

Syntax:
<div [ngClass]=" 'className' ">
<div [ngClass]="[ 'class1', 'class2' ]">
<div [ngClass]="{ 'class1:true', 'class2:false' }">

- The process of applying and changing a CSS class


dynamically for HTML element is known as "Class Binding".

Ex:classdemo.component.css
.text-style{
color: red;
text-align: center;
}
.border-style{
border: 2px solid red;
padding: 5px;
}
.back-style{
background-color: yellow;
}

Classdemo.component.html
<div class="container-fluid mt-2">
<h2 [ngClass]="'text-style'">Class Binding</h2>
<h2 [ngClass]="['text-style','border-style','back-
style']">Class Binding</h2>
<h3 [ngClass]="{'text-style':true,'border-
style':false,'back-style':true}">Class Binding</h3>
</div>

Ex:
classdemo.component.css

.dark-theme {
background-color: black;
color:white;
padding: 10px;
}
.invalid-style {
border:2px solid red;
box-shadow: 2px 2px 2px red;
}
.valid-style {
border:2px solid green;
box-shadow: 2px 2px 2px green;
}

classdemo.component.html

<div class="container-fluid">
<div class="d-flex justify-content-center align-items-center"
style="height: 400px;">
<form [ngClass]="{'dark-theme':Theme.value}">
<div class="form-switch">
<input type="checkbox" name="Theme" ngModel
#Theme="ngModel" class="form-check-input"> Dark Theme
</div>
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dd><input type="text" [ngClass]="{'invalid-
style':UserName.invalid, 'valid-style':UserName.valid}"
name="UserName" ngModel #UserName="ngModel" required
class="form-control"></dd>
<dt>Password</dt>
<dd><input type="password" [ngClass]="{'invalid-
style':Password.invalid, 'valid-style':Password.valid}"
name="Password" ngModel #Password="ngModel" required
minlength="4" class="form-control"></dd>
</dl>
<button class="btn btn-primary w-
100">Register</button>
</form>
</div>
</div>

NgStyle
======
- It is used to configure inline styles.
- Inline styles are native to element.
- NgStyle uses a style object that can change dynamically.
- You can configure styles for any element dynamically
according to state and situation.
- It doesn't require ".css" or external class, which will reduce
the number of request for component and improves the render
time.
- But have reusablity concerns.

Syntax:
styleObject = {
'styleAttribute' : value
}

<div [ngStyle]="styleObject"> </div>

- The process of configuring style object and applying to any


HTML element using inline style technique is known as "Style
Binding".

Ex:
classdemo.component.ts

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

@Component({
selector: 'app-classdemo',
templateUrl: './classdemo.component.html',
styleUrls: ['./classdemo.component.css']
})
export class ClassdemoComponent implements OnInit {
constructor() { }

ngOnInit(): void {
}
styleObject = {
'position': 'fixed',
'top': '',
'left': ''
}
MouseMove(event:any) {
console.log(`X=${event.clientX}\nY=${event.clientY}`);
this.styleObject = {
'position' : 'fixed',
'top': event.clientY + 'px',
'left': event.clientX + 'px'
}
}
}

classdemo.component.html

<div (mousemove)="MouseMove($event)">
<div class="container-fluid" style="height: 1000px;">

</div>
<img [ngStyle]="styleObject" src="assets/flag.gif"
width="50" height="50">
</div>

Note: You can configure a method that can return style object
and use the method for HTML element.

Syntax:
GetStyles() {
return {
'attribute': value
}
}

<div [ngStyle]="GetStyles()"> </div>

NgModel
=======
- It is an attribute directive that allocates memory for element
to store its value.
- NgModel is 'Single-Source-Of-Truth'.
- It can keep information about value and its changes.
a) Previous Value
b) Current Value
- It can bind value to property, identify changes in value and
update to source.

[(ngModel)] = 2 Way Binding


[] = property binding
() = event binding

Syntax: MVC

public UserName:string = 'John';

<input type="text" [(ngModel)]="UserName">

Syntax: MVVM

<input type="text" name="UserName"


ngModel #UserName="ngModel">
Note: "ngModel" is a member of "FormsModule" defined in
"@angular/forms".
Angular Event Binding
=================
- Event is a message sent by sender to its subscriber in order
to notify the change.
- Event follows a software design pattern called "Observer"
- Observer is a communication pattern.
- Angular uses all JavaScript events
a) Mouse Events mouseover, mouseout,
mousemove
b) Keyboard Events keyup, keydown, keypress
c) Clipboard Events cut, copy, paste
b) State Events focus, blur, change
e) Touch Events touchstart, touchmove,
touchend
f) Form Events submit, reset
h) Button Event click, dblclick, contextmenu
etc..

- JavaScript provides 2 default event arguments


a) this : contains information about the object,
like
id, name, className, value

b) event : contains infomraiton about event


properties like
clientX, clientY, altKey, keyCode, shiftKey etc..

Syntax:
<button onclick="ButtonClick(this, event)">

- Angular provides "$event" as default argument which


comprises of both event
and object properties.

$event : contains event properties


$event.target : contains object properties

Syntax:
<button (click)="ButtonClick($event)">

Keyboard Events:
- keyup
- keydown
- keypress

These are the events used to handle interactions when user


is keying-in the chars.
The key event related properties that are frequently used
- keyCode
- charCode
- which
- shiftKey
- altKey
- ctrlKey

Ex: KeyEvents

eventdemo.component.ts

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

@Component({
selector: 'app-eventdemo',
templateUrl: './eventdemo.component.html',
styleUrls: ['./eventdemo.component.css']
})
export class EventdemoComponent implements OnInit {
constructor() { }

ngOnInit(): void {
}
users:any[] = [
{UserName: 'john'},
{UserName: 'john12'},
{UserName: 'john_nit'},
{UserName: 'david'}
];
statusMessage:string = '';
isNameAvailable:boolean = true;
VerifyUser(e:any){
for(var user of this.users) {
if(user.UserName==e.target.value){
this.statusMessage = 'User Name Taken - Try
Another';
this.isNameAvailable = false;
break;
} else {
this.statusMessage = 'User Name Available';
this.isNameAvailable = true;
}
}
}
showCapsError:boolean = false;
VerifyPassword(e:any){
if(e.keyCode>=65 && e.keyCode<=90) {
this.showCapsError = true;
} else {
this.showCapsError = false;
}
}
}
eventdemo.component.html

<div class="container-fluid">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dd><input type="text"
(keyup)="VerifyUser($event)"></dd>
<dd [ngClass]="{'text-
success':isNameAvailable}">{{statusMessage}}</dd>
<dt>Password</dt>
<dd><input type="password"
(keypress)="VerifyPassword($event)" ></dd>
<dd class="text-warning" *ngIf="showCapsError">
<span class="bi bi-exclamation-triangle-fill"></span>
Caps ON
</dd>
</dl>
</div>

Angular Form Submit Event


- JavaScript uses form events
a) submit
b) reset

<form onsubmit="" onreset=""> </form>

- Angular provides "ngSubmit" for form submit, however you


also use "submit" of javascript.

<form (submit)="SubmitClick()">
<form (ngSubmit)="SubmitClick()">

- It allows to submit all form data to any API.


- Form data can be submitted only by using Angular Dynamic
Form.

- A Dynamic form is configured by using "ngForm" directive

Syntax:
<form #refName="ngForm">
<form #frmRegister="ngForm">

- Dynamic form compirses of various properties

#frmRegister.value : Submits all elements and


their values
frmRegister.pristing
.dirty
.valid
.invalid
Syntax:

<form #frmRegister="ngForm" (ngSubmit)="SubmitClick(frm


Register.value)">

<input type="text" name="UserName">


<select name="City">
<input type="number" name="Age">
<button type="submit"> Register </button>
</form>

SubmitClick(formObject:any)
{
alert(JSON.stringfy(formObject));
}
Angular Event Binding
What is Event?
• Event is a message sent by sender to its subscriber in order to
notify the change.
• Event follows a software design pattern called “Observer”.
• Observer is a communication pattern under “Behavioural
Patterns”.

• Angular implicitly controls all events by implementing


“EventEmitter” base.
• You can create custom event by using EventEmitter.
• Angular uses all JavaScript browser events
• Key Events
• Mouse Events
• Timer Events
• Miscellaneous Events
• Angular events are bound to HTML element by using “Event
Binding” technique
Syntax:
<button (click)=”method()”> </button>
<select (change)=”method()”> </select>
• Angular provides only one event argument that is “$event”
• You can access event related properties by using “event”
object.
• You can access object related properties by using “target”
object.
Syntax:
<button (click)=”method($event)”> </button>

public method(event) {
event.eventProperties;
event.target.objectProperties
}
Key Event Binding
• It defines the actions to perform when user is keying in the
characters.
• The key events are
Event Description
keyup Specifies actions to perform when key is
released
Keydown Specifies actions to perform when user hold
down a key
keypress Specifies actions to perform when user finish a
key.
[finish typing a key and use any another key]

• The key event properties


• shiftKey
• ctrlKey
• altKey
• keyCode
• charCode
• which
Note: Every key has a ASCII code you can get the code by using
• keyCode [65-90 – A-Z]
• charCode
• which
On Keyup and Keydown, the keyCode or Char code are not
captured.
Key and char code are accessible to any every only on key press.
Ex:
Keydemo.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-keydemo',
templateUrl: './keydemo.component.html',
styleUrls: ['./keydemo.component.css']
})
export class KeydemoComponent{
users = [
{UserName: 'john'},
{UserName: 'john123'},
{UserName: 'david'},
{UserName: 'david_nit'}
];
username;
password;
regExp = /(?=.*[A-Z])\w{4,10}/;

message = '';
validStyle = false;
invalidStyle = false;
showWarning = false;
passwordMessage = '';

VerifyUser(){
for(var user of this.users){
if(user.UserName == this.username) {
this.message = 'User Name Taken - Try Another';
this.invalidStyle = true;
this.validStyle = false;
break;
} else {
this.message = 'User Name Available';
this.invalidStyle = false;
this.validStyle = true;
}
}
}
VerifyCaps(e) {
if(e.keyCode>=65 && e.keyCode<=90) {
this.showWarning = true;
} else {
this.showWarning = false;
}
}
VerifyPasswordStrength(){
if(this.password.match(this.regExp)){
this.passwordMessage = 'Strong Password';
} else {
if(this.password.length<4) {
this.passwordMessage = 'Poor Password';
} else {
this.passwordMessage = 'Weak Password';
}
}
}
}
Keydemo.component.html
<div>
<div class="form-register">
<h2>Register User</h2>
<div class="form-group">
<label>User Name</label>
<div>
<input [ngClass]="{'valid-effect': validStyle, 'invalid-effect':
invalidStyle}" (keyup)="VerifyUser()" [(ngModel)]="username"
type="text" class="form-control">
<span [ngClass]="{'text-danger':invalidStyle, 'text-success':
validStyle}">{{message}}</span>
</div>
</div>
<div class="form-group">
<label>Password</label>
<div>
<input [(ngModel)]="password"
(keyup)="VerifyPasswordStrength()" (keypress)="VerifyCaps($event)"
type="password" class="form-control">
<div>
<span *ngIf="showWarning" class="text-warning"> <span
class="fa fa-exclamation-triangle"></span> Caps is ON </span>
</div>
<div>
<span> {{passwordMessage}} </span>
</div>
</div>
</div>
</div>
</div>
Keydemo.component.css
.form-register {
width: 300px;
border:2px solid darkcyan;
padding: 20px;
margin:auto;
margin-top: 20px;
border-radius: 10px;
}
.valid-effect {
border:2px solid green;
box-shadow: 2px 3px 4px green;
}
.invalid-effect {
border:2px solid red;
box-shadow: 2px 3px 4px red;
}

Mouse Event Binding


• Angular can use all JavaScript mouse events to handle various
interactions with regard to Mouse.
• The mouse events
• mouseover
• Specifies actions to perform when mouse pointer is
over the element.
• mouseout
• Actions to perform when pointer leaves the
element.
• mousedown
• Actions to perform when user hold down mouse
button.
• mouseup
• Actions to perform when mouse button is released
over element.
• mousemove
• Actions to perform when pointer is moving over
element.
• The commonly used event properties
• clientX
• clientY
Ex:
Mousedemo.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-mousedemo',
templateUrl: './mousedemo.component.html',
styleUrls: ['./mousedemo.component.css']
})
export class MousedemoComponent {
styleObj = {
'color': ''
};
zoomObject = {
'height': '',
'width': ''
};
offerImage = 'assets/giftbox.png';
SetColor(e){
this.styleObj = {
'color': e.target.id
};
}
startMarquee(e){
e.target.start();
}
stopMarquee(e){
e.target.stop();
}
zoomIN(){
this.zoomObject = {
'height': '400px',
'width': '400px'
};
}
zoomOut(){
this.zoomObject = {
'height': '100px',
'width': '100px'
};
}
showOffer(){
this.offerImage = 'assets/offerbox.png';
}
hideOffer(){
this.offerImage = 'assets/giftbox.png';
}
}
Mousedemo.component.html
<div>
<h2>Color Picker</h2>
<div class="row" (mouseover)="SetColor($event)" style="width:
500px; margin:auto">
<div class="col-4 bg-danger text-white" id="red">
Red
</div>
<div class="col-4 bg-success text-white" id="green">
Green
</div>
<div class="col-4 text-white" id="blue" style="background-color:
blue;">
Blue
</div>
</div>
<h2 align="center" [ngStyle]="styleObj" >Sample Text</h2>
<h2>Mouse over and out</h2>
<marquee (mouseover)="stopMarquee($event)"
(mouseout)="startMarquee($event)" scrollamount="10"
bgcolor="lightgreen">
<img src="assets/shoe.jpg" width="100" height="100">
<img src="assets/speaker.jpg" width="100" height="100">
<img src="assets/shirt.jpg" width="100" height="100">
<img src="assets/jeans.jpg" width="100" height="100">
</marquee>
<h2>Mouse Down and Up</h2>
<div style="width: 400px;">
<img [ngStyle]="zoomObject" (mousedown)="zoomIN()"
(mouseup)="zoomOut()" style="margin: auto;" src="assets/shoe.jpg"
width="100" height="100">
</div>
<h2>Mouse Down and Up</h2>
<div>
<img (mousedown)="showOffer()" (mouseup)="hideOffer()"
[src]="offerImage">
</div>
</div>
Mousedemo.component.css
img {
opacity: 0.8;
margin-left: 30px;
}
Other JavaScript Events used by Angular
Event Description
Blur Actions to perform when element loses the focus.
focus Actions to perform when element gets focus.
change Actions to perform when value is changed.
Cut
Copy
Paste
Select
Selectstart
Submit
Click
Dblclick
contextmenu

Ex:
Evendemo.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-eventdemo',
templateUrl: './eventdemo.component.html',
styleUrls: ['./eventdemo.component.css']
})
export class EventdemoComponent{
msg = '';
username;
products =
['assets/shoe.jpg','assets/shirt.jpg','assets/speaker.jpg','assets/earpo
ds.jpg'];
imageSource = 'assets/shoe.jpg';
sliderValue = 0;

onFocus(){
this.msg = 'Name in Block Letters';
}
onBlur(){
this.msg = '';
this.username = this.username.toUpperCase();
}
ChangeProduct(){
this.imageSource = this.products[this.sliderValue];
}
}
Evendemo.component.html
<div>
<h2>User Name</h2>
<div>
<input (focus)="onFocus()" (blur)="onBlur()"
[(ngModel)]="username" placeholder="Name in Block Letters"
type="text" class="form-control">
<span>{{msg}}</span>
</div>
<h2>Change</h2>
<div>
<label>Products</label>
<input [(ngModel)]="sliderValue" (change)="ChangeProduct()"
min="0" value="0" max="3" type="range">
</div>
<div>
<img [src]="imageSource" width="200" height="200">
</div>
</div>
Fakestore Shopping Cart

- Fakestore is an open source API with shopping data

http://fakestoreapi.com/

- API Requests

GET http://fakestoreapi.com/products
[returns all products data - 20]

GET http://fakestoreapi.com/products/1
[returns specific product]

GET http://fakestoreapi.com/products/categories
[returns all categories - 4]

GET http://fakestoreapi.com/products/category/jewel
ery
[returns all products belong to specific category]
(change) : It is an event that triggers the action when
value changed.
textbox, dropdown, range, number etc..

shoppingcart.component.ts

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

@Component({
selector: 'app-shoppingcart',
templateUrl: './shoppingcart.component.html',
styleUrls: ['./shoppingcart.component.css']
})
export class ShoppingcartComponent implements OnInit {

categories:string[] = [];

GetCategories(){
fetch('http://fakestoreapi.com/products/categories
HYPERLINK "http://fakestoreapi.com/products/categories&"&
HYPERLINK
"http://fakestoreapi.com/products/categories&"#39;)
.then(response=> response.json())
.then(data=> {
data.unshift("all");
this.categories = data;
})
}

products:any[] = [];

GetProducts(){
fetch('http://fakestoreapi.com/products HYPERLINK
"http://fakestoreapi.com/products&"& HYPERLINK
"http://fakestoreapi.com/products&"#39;)
.then(response=> response.json())
.then(data=> {
this.products = data;
})
}

constructor() { }

ngOnInit(): void {
this.GetCategories();
this.GetProducts();
}

CategoryChanged(e:any){
if(e.target.value=='all') {
this.GetProducts();
} else {
fetch(`http://fakestoreapi.com/products/category/${e.target
.value}`)
.then(response=> response.json())
.then(data=> {
this.products = data;
})
}
}

CartItems:any[] = [];
AddToCartClick(product:any){
this.CartItems.push(product);
alert(`${product.title} \nAdded to Cart`);
this.GetCartItemsCount();
}
count:number = 0;
GetCartItemsCount(){
this.count = this.CartItems.length;
}
toggleCart:boolean = false;
Toggle(){
this.toggleCart = (this.toggleCart==false)?true:false;
}
}

shoppingcart.component.html

<div class="container-fluid">
<header class="p-2 bg-danger text-white text-center">
<h1> <span class="bi bi-cart3"></span> Fakestore -
Online Shopping</h1>
</header>
<section class="row">
<nav class="col-3">
<div class="mt-3">
<label class="form-label">Select a Category</label>
<div>
<select (change)="CategoryChanged($event)"
class="form-select">
<option [value]="category" *ngFor="let category of
categories">
{{category|titlecase}}
</option>
</select>
</div>
</div>
<div class="mt-2" *ngIf="toggleCart">
<label>Your Cart</label>
<table class="table table-hover">
<thead>
<tr>
<th>Title</th>
<th>Price</th>
<th>Preview</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of CartItems">
<td>{{item.title}}</td>
<td>{{item.price}}</td>
<td><img [src]="item.image" width="50"
height="50"></td>
</tr>
</tbody>
</table>
</div>
</nav>
<main class="col-7">
<div class="d-flex flex-wrap m-3 overflow-auto"
style="height: 500px;">
<div *ngFor="let product of products" class="card m-2
p-2" style="width: 200px;">
<img [src]="product.image" height="150"
class="card-img-top">
<div class="card-header" style="height: 160px;">
<p><b>{{product.title}}</b></p>
</div>
<div class="card-body">
<dl>
<dt>Price</dt>
<dd>{{product.price}}</dd>
<dt>Rating</dt>
<dd><span class="bi bi-star-fill text-
success"></span> {{product.rating.rate}}
[{{product.rating.count}}]</dd>
</dl>
</div>
<div class="card-footer">
<button (click)="AddToCartClick(product)"
class="btn btn-danger w-100">
<span class="bi bi-cart4"></span>
Add to Cart
</button>
</div>
</div>
</div>
</main>
<article class="col-2">
<div class="mt-3">
<button (click)="Toggle()" class="btn btn-danger w-
100"> <span class="bi bi-cart"></span> [{{count}}] Your Cart
Items</button>
</div>
</article>
</section>
</div>
Custom Events
FAQ: Why we need custom events?
Ans: In Angular we can create custom components.
A component is used in another component for handling
specific functionality.
In this case a component have its own events to
perform.

FAQ: How data is transffered from parent to child component?


Ans:
- Child Component must have a property configured with
"@Input()"

Syntax:
@Input() Property:DataType = Value;

- Input() is a directive defined in "@angular/core"


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

- Parent component can access the child properties in UI.

<app-child [Property]="value"> </app-child>

- Parent component can send data into child property

message = "From Parent"

<app-child [message]="message"> </app-child>

Ex:
1. Add 2 components
> ng g c parent
> ng g c child

2. child.component.ts

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

@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

@Input() message:string|null = 'waiting for message from


parent..';
@Input() obj:any = {};
constructor() { }

ngOnInit(): void {
}
}

3. child.component.html

<div class="bg-dark text-white p-4" style="height: 200px;


width: 800px;">
<h3>Child Component</h3>
<p>{{message}}</p>
<p>Name : {{obj.Name}} <br> Price : {{obj.Price}}</p>
</div>

4. parent.component.ts

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

@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

messageToChild:string|null =null;
objectToChild:any = {};
constructor() { }

ngOnInit(): void {
}
SendClick(){
this.messageToChild = 'Hello ! from parent';
this.objectToChild = {
'Name': 'TV',
'Price': 45500.33
}
}
}

5. parent.component.html

<div class="container-fluid bg-danger m-4 p-4 text-white"


style="height: 400px; width: 1000px;">
<h2>Parent Component</h2>
<div class="mb-3">
<button (click)="SendClick()" class="btn btn-dark">Send
Message to Child</button>
</div>
<app-child [obj]="objectToChild"
[message]="messageToChild"></app-child>
</div>

FAQ: How data is transferred from child to parent component?


Ans:
- Child Component must configure a custom event.
- Every Angular event is defined by using EventEmitter
of '@angular/core'

Syntax:
CustomEvent:EventEmitter<any> = new
EventEmitter<any>();

- The values can be transffered by using a custom


event marked with
"@Output()"

Syntax:
@Output() CustomEvent:EventEmitter<any> = ....

- Custom event will emit a value or object on specific


child event.

Syntax:
onSendClick() {
this.CustomEvent.emit(value | object);
}

- Parent component can access the custom event of


child

<app-child (CustomEvent)> </app-child>

- Parent component must use a method to access event


args of child.

<app-child (CustomEvent)="Method($event)">
</app-child>

Method(e:any)
{
e.value|object_property
}

Ex:
1. child.component.ts

import { Component, OnInit, Input, EventEmitter, Output } from


'@angular/core';

@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() message:string|null = 'waiting for message from
parent..';
@Input() obj:any = {};
messageToParent = 'Hello ! from Child';

@Output() ChildComponentClick:EventEmitter<string> =
new EventEmitter<string>();
@Output()
ChildComponentSendObjectClick:EventEmitter<any> = new
EventEmitter<any>();

product:any = {'Name': 'Nike Casuals', 'Price': 6600.33};


constructor() { }

ngOnInit(): void {
}

SendClick(){
this.ChildComponentClick.emit(this.messageToParent);
this.ChildComponentSendObjectClick.emit(this.product);
}

2. child.component.html

<div class="bg-dark text-white p-4" style="height: 250px;


width: 800px;">
<h3>Child Component</h3>
<p>{{message}}</p>
<p>Name : {{obj.Name}} <br> Price : {{obj.Price}}</p>
<button (click)="SendClick()" class="btn btn-danger">Send
Message to Parent</button>
</div>
3. parent.component.ts

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

@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

messageToChild:string|null =null;
objectToChild:any = {};
message:string|null = null;
constructor() { }

ngOnInit(): void {
}
SendClick(){
this.messageToChild = 'Hello ! from parent';
this.objectToChild = {
'Name': 'TV',
'Price': 45500.33
}
}
SendToParent(e:any) {
this.message = e;
}
Name:string = '';
Price:number = 0;
SendObject(e:any) {
this.Name = e.Name;
this.Price = e.Price;
}
}
4. parent.component.html

<div class="container-fluid bg-danger m-4 p-4 text-white"


style="height: 400px; width: 1000px;">
<h2>Parent Component</h2>
<div class="mb-3">
<button (click)="SendClick()" class="btn btn-dark">Send
Message to Child</button>
{{message}} - {{Name}} : {{Price}}
</div>
<app-child
(ChildComponentSendObjectClick)="SendObject($event)"
(ChildComponentClick)="SendToParent($event)"
[obj]="objectToChild" [message]="messageToChild"></app-
child>
</div>
Ex:
1. Add following components
> ng g c products
> ng g c filter

2. filter.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from


'@angular/core';

@Component({
selector: 'app-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.css']
})
export class FilterComponent implements OnInit {

@Input() AllCount:number = 0;
@Input() ElectronicsCount:number = 0;
@Input() JeweleryCount:number = 0;
@Input() MensClothingCount:number = 0;
@Input() WomensClothingCount:number = 0;

@Output() FilterChanged:EventEmitter<string> = new


EventEmitter<string>();

constructor() { }

ngOnInit(): void {
}
FilterButtonClick(e:any){
this.FilterChanged.emit(e.target.name);
}

3. filter.component.html

<div style="text-align: left; font-size: 25px;">


<h3>Product Categories</h3>
<ul class="list-unstyled">
<li><button (click)="FilterButtonClick($event)" name="all"
class="btn btn-link">All [{{AllCount}}]</button></li>
<li><button (click)="FilterButtonClick($event)"
name="electronics" class="btn btn-link">Electronics
[{{ElectronicsCount}}]</button></li>
<li><button (click)="FilterButtonClick($event)"
name="jewelery" class="btn btn-link">Jewelery
[{{JeweleryCount}}]</button></li>
<li><button (click)="FilterButtonClick($event)"
name="mens' clothing" class="btn btn-link">Men's Clothing
[{{MensClothingCount}}]</button></li>
<li><button (click)="FilterButtonClick($event)"
name="women's clothing" class="btn btn-link">Women's
Clothing [{{WomensClothingCount}}]</button></li>
</ul>
</div>

4. products.component.ts

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

@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {

products:any[] = [];

allCount:number = 0;
electronicsCount:number = 0;
jeweleryCount:number = 0;
mensCount:number = 0;
womensCount:number = 0;

GetProducts(){
fetch('http://fakestoreapi.com/products HYPERLINK
"http://fakestoreapi.com/products&"& HYPERLINK
"http://fakestoreapi.com/products&"#39;)
.then(response=> response.json())
.then(data=>{
this.products = data;
this.allCount = data.length;
this.electronicsCount = data.filter((product:any)=>
product.category=='electronics').length;
this.jeweleryCount = data.filter((product:any)=>
product.category=='jewelery').length;
this.mensCount = data.filter((product:any)=>
product.category==`men's clothing`).length;
this.womensCount =
data.filter((product:any)=>product.category==`women's
clothing`).length;

})
}
constructor() { }

ngOnInit(): void {
this.GetProducts();
}
categoryName:string = 'all';
GetCategoryName(e:any){
this.categoryName = e;
if(this.categoryName=='all') {
this.GetProducts();
} else {
fetch(`http://fakestoreapi.com/products/category/${this.cat
egoryName}`)
.then(response=>response.json())
.then(data=>{
this.products = data;
})
}
}

5. products.component.html

<div class="container-fluid">
<header class="bg-danger text-white text-center p-2 mb-2">
<h2>Fake Store - Online Shopping</h2>
</header>
<section class="row">
<nav class="col-3">
<app-filter
(FilterChanged)="GetCategoryName($event)"
[AllCount]="allCount" [ElectronicsCount]="electronicsCount"
[JeweleryCount]="jeweleryCount"
[MensClothingCount]="mensCount"
[WomensClothingCount]="womensCount" ></app-filter>
</nav>
<main class="col-9">
<div class="d-flex flex-wrap overflow-auto"
style="height: 500px;">
<div *ngFor="let item of products" class="card m-2 p-
2" style="width: 200px;">
<img [src]="item.image" height="200" class="card-
img-top">
<div class="card-header" style="height: 170px;">
<p>{{item.title}}</p>
</div>
<div class="card-footer">
<p>{{item.price}}</p>
</div>
</div>
</div>
</main>
</section>
</div>
Component Life Cycle

- Every component in angular have to under go various


phases from start to end.
- Component life cycle starts when it is requested on index
page.
- Component life cycle end when another component is
requested or explicitly the component is closed. [Close
Application]
- The phases of component life cycle are mantained by using
a set of methods known as Life Cycle Hooks.
- The previous phase will hook to the next phase.
- Every component implicitly uses all these life cycle hooks.
- You can configure the hook method explicitly to define any
specific task to perform according state and situation.
- The component life cycle hook methods are:

1. ngOnChanges()
- This is the first life cycle hook method for component.
- It declares the reference.
- Assigns or initializes value into references.
- Binding the values to element properties or attributes.
- Identify the changes in value and update back to source.

public UserName:string = 'John'; // change detected


public UserName:string = undefined => 'John';

- ngOnChanges uses "SimpleChanges" class which


identifies
a) PreviousValue
b) CurrentValue

PreviousValue == CurrentValue // no change


detected
PreviousValue !== CurrentValue // change detected

public UserName:string = 'John'; // change detected

PreviousValue = undefined
CurrentValue = John

<input type="text" [value]="UserName"> //


change detection
<input type="text" (change)="Change()"> // change
detection

- ngOnChanges manages
a) Property Binding
b) Event Binding

FAQ: What is change detection?


Ans : It is the process of
- Initializing values into reference
- Binding the values to UI
- Identify the changes in UI and Update to source.
It is the process of
- initialization
- assignment
- property binding
- event binding

FAQ: Who manages change detection?


Ans : "SimpleChanges" object.

FAQ: Where change detection is managed?


Ans: In "ngOnChanges" phase.

2. ngOnInit()
- It initializes the memory for component, which is required
to store component data and use for the child component.
- Constructor allocates memory for component, but it is not
accessible to
child component.
- ngOnInit will initialize memory which is used for child
component to transport data.
3. ngDoCheck()
- Some values need explicit binding with properties.
- Some values need explicit events to identify changes.
- Changes in parent and update to child by using "@Input()"
- Values of child are emitted to parent by using "@Output()"
and custom event.
- It any value is not updated implicitly we have to configure
explicitly.
- It is managed by ngDoCheck.
- It manages transporting of data between parent and child.

FAQ: When Custom Events will fireup?


Ans: ngDoCheck

FAQ: When Default Events will fireup?


Ans: ngOnChanges

ngOnChanges()
ngOnInit()
ngDoCheck()
ngAfterContentInit():
================
- The output is generated into View.
- The results are binded to UI elements.
- It renders the initial output.
- Values stored in reference are rendered into View [UI].

<input type="text" [(ngModel)]="UserName">


Value is rendered into textbox
- The output is painted.

ngAfterContentChecked():
====================
- In this phase the external templates are rendered into UI.
- It will identify the templates by type "TemplateRef<T>"
- It will also identifies the dynamic templates in UI.
<ng-template>
- The templates are projected by @ViewChild() directive.
- Content Projection is managed in this phase.

ngAfterViewInit():
=============
- It initializes the memory for View [UI]
- This memory is used for transporting data across
components.
- It is used in MVVM approach.

<input type="text" [(ngModel)]="UserName"> memory not at


view level.

<input type="text" ngModel name="UserName"


#UserName="ngModel">

ngAfterViewChecked():
==================
- In this phase the final rendering and painting is processed.
- Rendering the preparing the final output.
- Painting is generating the output and displaying in browser.
- After ngOnChanges and ngAfterContentChecked the final
output is generated in this phase.

ngOnDestroy():
============
- The memory allocated for component will be cleaned.
- It unsubscribes to the memory.
- It disconnects with data reference.
- It unsubscribes to the methods.

<button (click)="InsertClick()"> => Sender


InsertClick() { } => Subscriber

Note: All Life Cycle Hooks are defined as contracts.


A component can implement multiple contracts.

FAQ: What is Content Projection?


FAQ: What is Change Detection?
Ans : Intialization or Assignment of values
Property Binding
Event Binding

FAQ: Who Manages Change Detection?


Ans : SimpleChanges object

FAQ: How change is identified?


Ans: By Accessing previous and current value.

FAQ: Who provides previous and current value?


Ans : SimpleChanges object

FAQ: Who is single-source-of-truth?


Ans: NgModel

FAQ: Why NgModel is single-source-of-truth?


Ans: It tracks the changes, identifies the value before and after
change.

Change Detection
===============
1. Add following components
> ng g c parent
> ng g c child

2. child.component.ts

import { Component, OnInit, Input, EventEmitter, Output,


OnChanges, SimpleChanges } from '@angular/core';

@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {

@Input() username:string = '';


previousvalue:string = '';
currentvalue:string = '';
msg:string = '';
constructor() { }

ngOnInit(): void {
}

ngOnChanges(changes: SimpleChanges): void {


for(var property in changes)
{
let change = changes[property];
this.currentvalue = change.currentValue;
this.previousvalue = change.previousValue;
}
if(this.currentvalue==this.previousvalue) {
this.msg = "No Change Detected";
} else {
this.msg = "Change Detected";
}
}

3. child.component.html

<div class="bg-dark text-white p-4" style="height: 250px; width:


800px;">
<h3>Child Component</h3>
<p>Hello ! {{username}}</p>
<h3>{{msg}}</h3>
<p>
Previous Value :
{{(previousvalue==undefined)?"Undefined":previousvalue}}
<br>
Current Value : {{currentvalue}}
</p>
</div>

4. parent.component.ts

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

@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}
UserName:any = 'David';
}

5. parent.component.html

<div class="container-fluid bg-danger m-4 p-4 text-white"


style="height: 400px; width: 1000px;">
<h2>Parent Component</h2>
<dl>
<dt>User Name</dt>
<dd><input [(ngModel)]="UserName" type="text"></dd>
</dl>
<app-child [username]="UserName"></app-child>
</div>

FAQ : When content projection happens in Angular Component


LifeCycle?
Ans: ngAfterContentChecked()

FAQ: When Change Detection happens?


Ans: ngOnChanges()

FAQ: When Custom Events fire up?


Ans: ngDoCheck()

FAQ: When default Events fire up?


Ans : ngOnChanges()

FAQ: When methods are unsubscribed?


Ans: ngOnDestroy()

FAQ: When Painting performed?


Ans: ngAfterViewChecked()
Implementing 3rd Party Components
- Telerik
- DevExpress
- Material UI [Angular Team]

Angular Material

• Material provides UI and UX components form Angular.


• It is native to Angular.
• It is built-by Google Angular Team
• Provide Unified UX across devices.

Install Angular Material


• You have to add “Angular Material” to existing project.
• Run the following command in Angular Workspace
> ng add @angular/material
*Would you like to add Typography? Y
*Select a Pre-built Theme: Choose any theme
*Add Browser Animations Module? Y
• This will update following files
• package.json
• index.html
Roboto font
• angular.json
Configure Styles
• app.module.ts
• Setup theme file in “Styles.css”
@import '@angular/material/prebuilt-themes/indigo-
pink.css';

Angular Components
How to Explore Components?
• Visit https://material.angular.io/components
• Select any component
• Go to “API” tab to know about the properties, methods and
modules required for component
• Know your component module name
• Know the dependencies for required module
• Know the selector for component
• Know the properties and methods for component

Component: Form Field [Directive as Element]


• Module Required for Form Field
• MatFormFieldModule
• Dependencies
• MatError
• MatFormField
• MatHint
• MatPlaceholder
• MatPrefix
• MatSuffix
• MatLabel
• Get Selector Name from API
• mat-form-field
• Get Properties from API
• @Input() appearance: MatFormFieldAppearance
[appearance]
• @Input() color: ThemePalette [color]
• Go to “Interfaces” category in API to get information about
property values.
• MatFormFieldAppearance = 'legacy' | 'standard' | 'fill' |
'outline'

Syntax:
<mat-form-field appearance=”legacy | standard | fill |
outline”>
</mat-form-field>

Component: Input [Directive as Attribute]


• Module
• MatInputModule
• Attribute Name
• matInput
Syntax:
<input type=”text” matInput>

Ex: Implementing Material Components


• Go to “app.module.ts”
import { MatFormFieldModule } from
'@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';

@NgModule({
imports: [
BrowserModule,
FormsModule,
BrowserAnimationsModule,
MatFormFieldModule,
MatInputModule
],
})
• Go to your “component.html”
<div class="container">
<h2>Material Demo</h2>
<mat-form-field appearance="legacy" class="block-style" >
<mat-label>User Name</mat-label>
<input [(ngModel)]="UserName" type="text" matInput
placeholder="Enter User Name">
<mat-hint>Name in Block Letters</mat-hint>
<mat-error>Name Required</mat-error>
</mat-form-field>
<h3>Hello ! {{UserName}} </h3>
</div>
• Component.css
.block-style {
width: 100%;
}
• Component.ts
UserName = ‘ ‘;

Material Datepicker
• Modules
• MatDatepickerModule
• MatNativeDateModule
• Selectors
• mat-datepicker-toggle
• mat-datepicker

Ex:
• Import the following modules in “app.module.ts”
import { MatNativeDateModule } from
'@angular/material/core';
import { MatFormFieldModule } from
'@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from
'@angular/material/datepicker';
imports: [
BrowserModule,
FormsModule,
BrowserAnimationsModule,
MatFormFieldModule,
MatInputModule,
MatDatepickerModule,
MatNativeDateModule
],

Component.html
<mat-form-field class="block-style mt-3">
<mat-label>Departure Date</mat-label>
<input type="text" matInput [matDatepicker]="picker" >
<mat-datepicker-toggle matSuffix [for]="picker" ></mat-
datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>

Material Icons
Ex:
App.module.ts
import { MatIconModule } from '@angular/material/icon';
imports: [
BrowserModule,
FormsModule,
BrowserAnimationsModule,
MatFormFieldModule,
MatInputModule,
MatDatepickerModule,
MatNativeDateModule,
MatIconModule
],
<button>
<mat-icon>home</mat-icon>
Home
</button>

Angular CDK
(Component Dev Kit)
• It defines set of behaviour primitives for build UI component.
• It provides UX [User Experience]

Implementing Lazy Loading with Virtual Scroll CDK


• Lazy loading allows to load only the content required for
situation.
• <cdk-virtual-scroll-viewport>
• *cdkVirtualFor

Ex:
App.module.ts
import { ScrollingModule } from '@angular/cdk/scrolling';
[
ScrollingModule
]

Component.ts
products = [
{Name: 'JBL Speaker', Photo: 'assets/speaker.jpg'},
{Name: 'Earpods', Photo: 'assets/earpods.jpg'},
…. Add records
]
Component.html
<div class="container">
<h2>Lazy Loading - Virtual Scrolling</h2>
<cdk-virtual-scroll-viewport itemSize="100" class="view-port" >
<div class="card" *cdkVirtualFor="let product of products">
<img [src]="product.Photo" height="50" class="card-img-top">
<div class="card-body">
<h2>{{product.Name}}</h2>
</div>
</div>
</cdk-virtual-scroll-viewport>
</div>
Angular Material UI Components
mat-form-field
matinput

Ex: Date Picker


<input type="date"> - Not compatible for various browsers.

Exploring UI components and Implementing


=================================
1. Go to "material.angular.io"
2. Go to "components" category
3. Select any component : DatePicker
4. Go to "API" category in documentation to get information about
the module
required for component.

import {MatDatepickerModule} from


'@angular/material/datepicker';

5. Import into "app.module.ts" and register

imports: [
MatDatepickerModule
]

6. DatePicker requires "MatNativeDateModule" adapter


from "@angular/material/core".

7. Import into "app.module.ts"

import {MatDatepickerModule} from


'@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
imports: [
MatDatepickerModule,
MatNativeDateModule
]

8. Implement in your component


[materialdemo.component.html]

<div class="container-fluid">
<h2>Date Picker</h2>
<mat-form-field appearence="legacy" >
<mat-label>Departure</mat-label>
<input matInput [matDatepicker]="picker" type="text">
<mat-datepicker-toggle matSuffix [for]="picker" ></mat-
datepicker-toggle>
<mat-datepicker #picker ></mat-datepicker>
</mat-form-field>
</div>

matSuffix & matPreffix : To configure any element as preffix or


suffix
these are the members of "mat-form-field"

[for] : It is used to bind the toggler with datepicker

[matDatepicker] : It is used by input to access and display


date
from calender.

Material CDK
==========
- It provides behaviour for components.
- It is Component Development Kit

Ex: Lazy Loading


*ngFor : Eager loading
*ngVirtualFor : Lazy Loading
<cdk-virtual-scroll>

Angular Animations
---------------------------
- You can apply CSS transitions and transforms dynamically
to angular components.

- CSS Transforms
2D
3D
translate()
rotate()
scale()
skew()
matrix()
- CSS Transition
transition-duration
transition-delay
transition-property
transition-timing-function

- Angular animations are similar to @keyframes

@keyframes name
{
from { }
to { }
}

p{
animation-name: keyframeName
}

- Angular animations required "animations[]" meta data


defined in "@component()" directive.

@Component(
{
selector: 'app-login',
templateUrl: 'htmlPage',
stylesUrl: [ 'stylesheet' ],
animations: [ ]
}
)

- Angular animation requires various methods defined


in "BrowserAnimationsModule" of "@angular/animations".

- Angular animations library is installed along with "Material".

- Angular animation methods

trigger() It comprises of set of animations store


under
a specific name. It is similar to @keyframes

state() It defines initial and final state.


[from .. to]

state('initial=>final') state('void=>*')
state('final=>initial') state('*=>void')

styles() It defines the set of style attributes to


apply.

animate() It is used to define duration of


animation.

transition() It defines the state and timing between


initial and final state.

Syntax:
animations: [
trigger('name',
state('initial', styles({ })),
state('final', styles({ })),
transition('initial=>final', animate(4000)),
transition('final=>initial', animate(5000))
)
]

<h2 [@triggerName]='initial'>

Note: Angular animation is all about changing the animation


state dynamically.

Ex:
1. Add a new component
> ng g c animationdemo --skip-tests

2. animationdemo.component.ts

import { trigger, state, style, transition, animate } from


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

@Component({
selector: 'app-animationsdemo',
templateUrl: './animationsdemo.component.html',
styleUrls: ['./animationsdemo.component.css'],
animations: [
trigger('zoom', [
state('initial', style(
{
'width': '100px',
'height': '100px',
'transform': 'rotate(0deg)'
}
)),
state('final', style({
'width': '300px',
'height': '300px',
'transform': 'rotate(360deg)'
})),
transition('initial=>final', animate(4000)),
transition('final=>initial', animate(3000))
])
]
})
export class AnimationsdemoComponent implements OnInit {

animationState:any = 'initial';
buttonText:string = 'In';
constructor() { }

ngOnInit(): void {
}
ZoomClick(){
this.animationState =
(this.animationState=='initial')?'final':'initial';
this.buttonText = (this.buttonText=='In')?'Out':'In';
}
ZoomInClick(){
this.animationState = 'final';
}
ZoomOutClick(){
this.animationState = 'initial';
}

3. animationdemo.component.html

<div class="container-fluid text-center">


<div class="mb-3 mt-3">
<div class="btn-group">
<button (click)="ZoomOutClick()" class="btn btn-
primary">-</button>
<button (click)="ZoomClick()" class="btn btn-
dark">Zoom {{buttonText}}</button>
<button (click)="ZoomInClick()" class="btn btn-
primary">+</button>
</div>
</div>
</div>
<div class="d-flex container-fluid justify-content-center align-
items-center" style="height: 400px;">
<div>

<div>
<img (mouseover)="ZoomInClick()"
(mouseout)="ZoomOutClick()" [@zoom]="animationState"
src="assets/shoe.jpg" width="100" height="100">
</div>

</div>
</div>
Ex: Multiple Triggers

component.ts

import { trigger, state, style, transition, animate } from


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

@Component({
selector: 'app-animationsdemo',
templateUrl: './animationsdemo.component.html',
styleUrls: ['./animationsdemo.component.css'],
animations: [
trigger('zoom', [
state('initial', style(
{
'font-size':'20px',
'transform': 'rotate(0deg)'
}
)),
state('final', style({
'font-size': '80px',
'transform': 'rotate(360deg)'
})),
transition('initial=>final', animate(4000)),
transition('final=>initial', animate(3000))
]),
trigger('zoomImage', [
state('initial', style(
{
'width':'100px',
'height': '100px',
'transform': 'rotate(0deg)'
}
)),
state('final', style({
'width':'200px',
'height': '200px',
'transform': 'rotate(360deg)'
})),
transition('initial=>final', animate(4000)),
transition('final=>initial', animate(3000))
])
]
})
export class AnimationsdemoComponent implements OnInit {

animationState:any = 'initial';
buttonText:string = 'In';
constructor() { }

ngOnInit(): void {
}
ZoomClick(){
this.animationState =
(this.animationState=='initial')?'final':'initial';
this.buttonText = (this.buttonText=='In')?'Out':'In';
}
ZoomInClick(){
this.animationState = 'final';
}
ZoomOutClick(){
this.animationState = 'initial';
}

component.html

<div class="container-fluid text-center">


<img src="assets/shoe.jpg"
[@zoomImage]="animationState" width="100" height="100">
<div class="mb-3 mt-3">
<div class="btn-group">
<button (click)="ZoomOutClick()" class="btn btn-
primary">-</button>
<button (click)="ZoomClick()" class="btn btn-
dark">Zoom {{buttonText}}</button>
<button (click)="ZoomInClick()" class="btn btn-
primary">+</button>
</div>
</div>
</div>
<div class="d-flex container-fluid justify-content-center align-
items-center" style="height: 400px;">
<div>

<div>
<h1 [@zoom]="animationState">Welcome to
Angular</h1>
</div>

</div>
</div>

End of Components

Angular Pipes
============
- Angular is used in front end to consume data from API and
present in UI.
- Data comes from various sources, Angular can't present the
data exactly how it is defined.
- You have to Transform data and present in UI.
- Pipes are used to Transform data.
- Pipes are used to format the data.
- Angular provides pre-defined Pipes [Built-in Pipes]
AsyncPipe
UpperCasePipe
LowerCasePipe
TitleCasePipe
NumberPipe
CurrencyPipe
SlicePipe
PercentPipe
JsonPipe
i18nSelectPipe
i18nPluralPipe
DatePipe
- Angular also allows to create Custom Pipes
- Angular Pipes are classified into 2 groups by developers
a) Pure Pipe [ Only Format Changes ]
b) Impure Pipe [ Can Change Data]
- Angular Pipe can be parameter less or parameterized.

Syntax:
data | pipeName:parameter1:parameter2

Pipe Architecture
=============
- Every Pipe is a class that implements "PipeTransform"
contract.

export class PipeName implements PipeTransform


{
transform(value:any, ...args[]) {
value is formatted.
return value;
}
}
- Pipe() directive is used to mark your TypeScript class as a
Pipe.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'pipename'
})
export class PipeName implements PipeTransform
{
transform(){ }
}

Ex: Custom Pipe - Parameterless


===========================

1. Add a new folder into "app" by name


"pipes"

2. Add a new file into pipes folder by name

sentencecase.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'sentencecase'
})
export class SentenceCasePipe implements PipeTransform
{
transform(value:any) {
let firstChar = value.charAt(0);
let restChars = value.substring(1);
let sentence =
firstChar.toUpperCase()+restChars.toLowerCase();
return sentence;
}
}

3. Go to "app.module.ts" import and register pipe

import { SentenceCasePipe } from


'./pipes/sentencecase.pipe';

declarations: [
SentenceCasePipe
]

4. Add a new component


> ng g c pipedemo --skip-tests

5. pipedemo.component.ts

title:string = 'wElCOMe To AnGUlaR';

6. pipedemo.component.html

<h1>{{title | sentencecase}}</h1>

Note: You can create and add pipe into project by using CLI
commands

>ng g pipe pipeName --skip-tests

Ex: Parameteried Pipe - Sorting

1. Generate a new Pipe


> ng g pipe sorting skip-tests
2. Customize the pipe

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'sorting'
})
export class SortingPipe implements PipeTransform {

transform(list:any, reverse?:boolean) {
list.sort();
if(reverse==true){
list.sort();
list.reverse();
}
return list;
}

3. pipedemo.component.ts

cities:any[] = ['Delhi','Chennai', 'Hyd', 'Mumbai', 'Bangalore',


'Goa'];

4. pipedemo.component.html

<div class="container-fluid">
<h2>Cities</h2>
<ol>
<li *ngFor="let item of cities|sorting:true">
{{item}}
</li>
</ol>
</div>
Note : You can chain pipes.

<li *ngFor="let item of cities|sorting:true | slice:0:3">


{{item}}
</li>

Angular Built-in Pipes


=================
- uppercase
- lowercase
- titlecase
- slice
Angular Pipes
• Pipe is used to transform data.
• Data comes to your Angular application from various sources.
• The data type of provider and the TypeScript types will not
match.
• The data is not displayed in the same format how we are
expecting.
• Pipe can transform the data and display in desired format.
• Angular pipes are used for formatting and filtering the data.
• Angular allows to create custom pipes and also provides pre-
defined pipes.
• All Angular pipes are derived from “PipeTransform” base.
• Every pipe implements a functionality by using “transform()”
method.
• Pipe related meta data is defined by using “@Pipe()” marker.
Syntax:
import { PipeTransform } from ‘@angular/core’;
@Pipe({
name: ‘uppercase’
})
export class UpperCasePipe implement PipeTransform
{
transform(value) {
// transform your value
// return the transformed value
return value;
}
}
{{ product.Name | uppercase }}
• Angular provides built-in pipes
• AsyncPipe [Observable, Subscribers – RxJS – HttpServices]
• CurrencyPipe
• DatePipe
• DecimalPipe
• I18PluralPipe
• I18SelectPipe
• JsonPipe
• KeyValuePipe
• LowerCasePipe
• UpperCasePipe
• TitleCasePipe
• PercentPipe
• SlicePipe
• Angular Pipes are by default “Pure” pipes.
• They will not change the value; they just define a format for
value.
• If a Pipe can change the state and value then it is “Impure”
pipe.
• Pipe can accept arguments and can modify the functionality of
pipe. [often referred as Parameterized pipes]
Syntax:
{{ data | pipe:option1:option2 | pipe }}

Pipe Name Description


UpperCasePip uppercas It converts all letters into block
e e letters.
EX:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};
{{product.Name | uppercase}}
LowerCasePip lowercase It converts all letters into lowercase
e letter.

Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};
{{product.Name | lowercase}}
TitleCasePipe titlecase It converts every word first char to
uppercase.
Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};
{{product.Name | titlecase}}
DecimalPipe number It is used to display numeric value
with thousands separator and
fractions.

It comprises of following parameters:


Minimum-Integer-Digits
Minimum-Fraction-Digits
Maximum-Fraction-Digits

Syntax:
{{data | number:
{minIntegerDigits}:{minFractionDigits}
-{maxFractionDigits} }}

Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};

{{product.Price | number:’4.2-4’}}
CurrencyPipe currency It is similar to decimal pipe but have a
currency symbol to display.

Syntax:
{{data | currency: ‘CurrencyFormat’:
‘digitsInfo’}}
Currency Format you can define
“USD, INR, etc.”
You can also define literals “&#8377;”

Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};
{{ product.Price | currency: ‘INR’ }}
{{ product.Price | currency: ‘&#8377;’
}}
DatePipe date It is used for displaying date and time
value in various date and time
formats.

You can use predefined date formats:


• short
• medium
• long
• full
• shortDate
• mediumDate
• longDate
• fullDate
• shortTime
• mediumTime
• longTime
• fullTime

Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};

{{product.Mfd | date: 'shortDate'}}

You can also define custom format


for date.
MM – 2 digits month
MMM – short month name
MMMM – long month name
dd - 2 digits date
d – 1 digit date
yy – 2 digits year
yyyy – 4 digits year

Syntax:
{{ data | date: ‘MM-dd-yyyy’}}
{{product.Mfd | date: 'MMMM-dd-
yyyy'}}
PercentPipe percent Transforms a number into percentage
string.

Syntax:
{{data | percent: ‘digitsInfo’ }}

Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10'),
Sales: 0.259
};
{{product.Sales | percent:'2.2-2'}}
SlicePipe slice It creates a new array or string
containing subset of the elements.
It can extract values based on
specified index and return an array.

{{ collection |
slice:startIndex:endIndex }}

Ex:
products = ['TV', 'Mobile', 'Speaker',
'Shoe', 'Shirt'];

<ol>
<li *ngFor="let item of products |
slice:1:3">
{{item}}
</li>
</ol>
JsonPipe json It converts the data into JSON format,
so that can transport to server-side
services.

Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10'),
Sales: 0.259
};
<div>
<pre>
{{product | json}}
</pre>
</div>
KeyValuePipe keyvalue It allows to read the properties and
values from a collection.
“Key” is used to access the keys or
properties
“Value” is used to access the values.
You can configure on a collection like
“Array or Map”.

Ex:
data: {[key:number]:string} = {
1001: 'Samsung TV',
1002: 'Nike Casuals'
};
products = ['TV', 'Mobile', 'Speaker',
'Shoe', 'Shirt'];

<div class="container-fluid">
<h2>Array</h2>
<ol style="list-style: none;">
<li *ngFor="let item of products |
keyvalue">
[{{item.key}}] {{item.value}}
</li>
</ol>
<h2>Map</h2>
<ol style="list-style: none;">
<li *ngFor="let item of data |
keyvalue">
{{item.key}} - {{item.value}}
</li>
</ol>
</div>
I18nSelectPipe i18select • i18 is community of Angular.
• It designed SelectPipe.
• It is a generic selector that can
make decision dynamically
according to the state or values
and define result when the
relative condition is matching.
• In early version we have to
depend on lot of iterations and
conditions.

Syntax:
{{value_expression |
i18select:mapping}}

• It is an impure pipe.

Ex:
export class PipedemoComponent{
products = [
{Name: 'Samsung TV', City: 'Delhi'},
{Name: 'Nike Casuals', City:
'Hyderabad'},
{Name: 'Mobile', City: 'Delhi'},
{Name: 'Shirt', City: 'Goa'}
];
statusMessage = {
'Hyderabad': 'Delivery in 2 Days',
'Delhi': 'Delivery on same Day',
'Mumbai': 'Not Deiverable',
'other': 'Unknow - We Will Update'
};
}

<div class="container-fluid">
<h2>Products Status</h2>
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>City</th>
<th>Delivery Status</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of
products">
<td>{{item.Name}}</td>
<td>{{item.City}}</td>
<td>{{item.City |
i18nSelect:statusMessage}}</td>
</tr>
</tbody>
</table>
</div>
I18PluralPipe i18plural • As per coding standards we use
plural name of multiple items or
collection and singular name for
one object.
Syntax:
product = {};
products = [];
• Plural Pipe can identify whether
the object comprises of single or
multiple value and define a
plural name dynamically.
• It can get collection count and
display messages according to
count.
• It uses a map to verify the
values.
Syntax:
{{collection.length |
i18plural:keyValueCollection}}

Ex:
• Go to “app.module.ts” and import following modules
import { MatIconModule } from '@angular/material/icon';
import { MatBadgeModule } from '@angular/material/badge';

imports: [
MatIconModule,
MatBadgeModule
],
• Pluraldemo.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-pluraldemo',
templateUrl: './pluraldemo.component.html',
styleUrls: ['./pluraldemo.component.css']
})
export class PluraldemoComponent{
notifications = [];
notificationsMap: {[key:string]:string} = {
'=0': 'No Missed Calls', '=1': 'One Missed Call', 'other': '#
Missed Calls'
};
showCalls = false;
ManagerClick(){
this.notifications.push('Call From Manager');
}
AdminClick(){
this.notifications.push('Call from Admin');
}
GetMissedCalls() {
this.showCalls = true;
}
}
• Pluraldemo.component.html
<div class="container-fluid">
<h2>Plural Demo</h2>
<div class="form-group">
<button (click)="ManagerClick()">Call From
Manager</button>
<button (click)="AdminClick()">Call From Admin</button>
</div>
<mat-icon
matBadge="{{notifications.length}}">phone</mat-icon>
<span style="cursor: grab;" (click)="GetMissedCalls()">
{{notifications.length | i18nPlural:notificationsMap}}
</span>
<div *ngIf="showCalls" class="form-group">
<h3>Missed Calls</h3>
<ul>
<li *ngFor="let item of notifications">
{{item}}
</li>
</ul>
</div>
</div>

Custom Pipe
• You can create your own pipe that can transform data.
• To create a pipe, you need create a class that implement
“PipeTranform”
• You have to configure the functionality by using “transform()”
Ex:
• Add a new folder
“CustomPipes”
• Add a new file
Sentencecase.pipe.ts
import { PipeTransform, Pipe } from '@angular/core';

@Pipe(
{name: 'sentencecase'}
)
export class SentenceCasePipe implements PipeTransform {
transform(str){
let firstChar = str.charAt(0);
let restChars = str.substring(1);
let sentence = firstChar.toUpperCase() +
restChars.toLowerCase();
return sentence;
}
}
• Go to “app.module.ts” and register the pipe in declarations
declarations : [
SentenceCasePipe
]
• Apply for your content
msg = “wELCome TO AGulaR”;

{{ msg | sentencecase }}

Try:
• Create a pipe for sorting and printing the list of values from
array.
Somecollection = [ ]

<li *ngFor=”let item of somecollection | yourPipe”>


sort()
reverse()

Angular Services
• Service is a pre-defined business logic which can be reused in
the application by injecting into any component.
• Service is a collection of Factories.
• Factory is a collection of related type of functions.
• You can inject a factory into any component in order to use the
functionality.
• Factory uses a single call mechanism. Every time when you
want to use a function you need an object to create.
[Disconnected – Discrete]
• Service uses a Single Ton mechanism. Object is created for first
request and the same object is used across any number of
requests. [Connected – Continuous]
• Angular service is a class with a set of functions [service
methods] that return any specific functionality.
• Angular service implements the functionality from
“Injectable()” directive.
• Injectable allows service to use a single ton mechanism so that
it can be injected into any component.

Syntax:
Import { Injectable } from ‘@angular/core’;
@Injectable(
providedIn: ‘root’
) // decorator for service
export class ServiceName {
serviceMethod() { }
}
• You have to register a service in order use in application.
Services are registered in “app.module.ts” at
providers: [ ServiceName ]
• CLI command for generating service:
> ng g service serviceName –skipTests

Ex:
• Add a new file into “app” folder
“captcha.service.ts”

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

@Injectable({
providedIn: 'root'
})
export class CaptchaService {
public GenerateCode() {
let a = Math.random() * 10;
let b = Math.random() * 10;
let c = Math.random() * 10;
let d = Math.random() * 10;
let e = Math.random() * 10;
let f = Math.random() * 10;
let code = `${Math.round(a)} ${Math.round(b)}
${Math.round(c)} ${Math.round(d)} ${Math.round(e)}
${Math.round(f)}`;
return code;
}
}
• Register service in “app.module.ts”

providers: [ CaptchaService ],

• Inject into “LoginComponent”


• login.component.ts

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


import { CaptchaService } from '../captcha.service';
@Component({
selector: 'app-login',
templateUrl: 'login.component.html',
styleUrls: ['login.component.css']
})
export class LoginComponent {
public code;
constructor(private captcha: CaptchaService) {
this.code = captcha.GenerateCode();
}
public title = 'User Login';
public NewCode() {
this.code = this.captcha.GenerateCode();
}
}
• login.component.html

<div class="box">
<h2>{{title}}</h2>
<div class="group">
<label>User Name</label>
<div>
<input type="text">
</div>
</div>
<div class="group">
<label>Password</label>
<div>
<input type="password">
</div>
</div>
<div class="group">
<label>Verify Code</label>
<div>
<button (click)="NewCode()">{{code}} <span class="fa fa-
sync-alt"></span></button>
</div>
</div>
<div class="group">
<button>Login</button>
</div>
</div>
• login.component.css

.box {
justify-content: center;
align-items: center;
margin:auto;
width:300px;
border:2px solid darkcyan;
box-shadow: 2px 2px 3px darkcyan;
padding: 10px;
margin-top: 20px;
}
.group {
margin-bottom: 20px;
}
button {
background-color: darkcyan;
color:white;
}

Ex: Data
• Generate a service
• ng g service data --skipTests
• data.service.ts

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

@Injectable()
export class DataService {
public GetProducts(){
return [
{Name: 'JBL Speaker', Price: 45000.55, Photo:
'assets/jblspeaker.jpg', Category: 'Electronics'},
{Name: 'Earpods', Price: 4000.55, Photo:
'assets/earpods.jpg', Category: 'Electronics'},
{Name: 'Nike Casuals', Price: 9000.55, Photo:
'assets/shoe.jpg', Category: 'Footwear'},
{Name: 'Lee Cooper Boot', Price: 3000.55, Photo:
'assets/shoe1.jpg', Category: 'Footwear'},
{Name: 'Shirt', Price: 2600.55, Photo: 'assets/shirt.jpg',
Category: 'Fashion'},
{Name: 'Jeans', Price: 2000.55, Photo: 'assets/jeans.jpg',
Category: 'Fashion'}
];
}
}
• Goto “app.module.ts” and register service
providers: [ CaptchaService, DataService ],

• Productslist.component.ts

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


import { DataService } from '../data.service';

@Component({
selector: 'app-productslist',
templateUrl: './productslist.component.html',
styleUrls: ['./productslist.component.css']
})
export class ProductslistComponent implements OnInit {
constructor(private data: DataService){

}
public products = [];
ngOnInit() {
this.products = this.data.GetProducts();
}

public ElectronicCount =
this.products.filter(x=>x.Category=='Electronics').length;
public FootwearCount =
this.products.filter(x=>x.Category=='Footwear').length;
public FashionCount =
this.products.filter(x=>x.Category=='Fashion').length;
public selectedCategoryValue = 'All';
public onFilterCategoryChanged(selectedCategoryName) {
this.selectedCategoryValue = selectedCategoryName;
}
}
HttpClient Service
==============
- fetch() is a JavaScript method for interacting with API.
- HttpClient is a service provided by Angular for interacting
with API.

FAQ: What is difference between fetch() and HttpClient?


Ans :
Fetch:
- fetch() returns the data in binary format.
- You have to convert data into JSON explicitly.
- It uses blocking technique
- It can be blocked by CORS. [Cross Origin Resource
Sharing]

HttpClient:
- It returns data in JSON format.
- It uses "RxJS" library, which makes HttpClient
Asynchronous.
- It uses unblocking technique.
- It can handle CORS
- It is faster than fetch()
- HttpClient service is defined under "HttpClientModule" of
"@angular/common/http" library

- RxJs library is required for Asynchronous calls.


> npm install rxjs

- RxJs library comprises


a) Observable
b) Subscriber

- Observable defines the actions to performs.


- Subscriber is used to execute actions.

Syntax:
GetProducts:Observable<T>() {

GetProduct.subscribe(data=> { })

Ex:
1. Go to "app.module.ts"

import { HttpClientModule } from '@angular/common/http';

imports: [
HttpClientModule
]

2. Goto "services" folder and add a new file

"Fakestoreapi.service.ts"

import { Injectable } from "@angular/core";


import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";

@Injectable({
providedIn: 'root'
})
export class FakestoreapiService
{
constructor(private http: HttpClient){}
GetCategories():Observable<string[]>{
return
this.http.get<string[]>('http://fakestoreapi.com/products/catego
ries HYPERLINK
"http://fakestoreapi.com/products/categories&"& HYPERLINK
"http://fakestoreapi.com/products/categories’);
}
GetProducts():Observable<any[]>{
return
this.http.get<any[]>('http://fakestoreapi.com/products
HYPERLINK "http://fakestoreapi.com/products&"&
HYPERLINK "http://fakestoreapi.com/products”);
}
}

3. Go to Components and add a new component

> ng g c fakestore

4. fakestore.component.ts

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


import { FakestoreapiService } from
'../../services/fakestoreapi.service';

@Component({
selector: 'app-fakestore',
templateUrl: './fakestore.component.html',
styleUrls: ['./fakestore.component.css']
})
export class FakestoreComponent implements OnInit {

constructor(private fakestore: FakestoreapiService) { }

categories:string[] = [];
products:any[] = [];

ngOnInit(): void {
this.fakestore.GetCategories().subscribe(category=>
this.categories = category );
this.fakestore.GetProducts().subscribe(product=>
this.products = product);
}

5. fakestore.component.html

<div class="container-fluid">
<div class="row">
<div class="col-3">
<div>
<label class="form-label">Select Category</label>
<div>
<select class="form-select">
<option *ngFor="let item of categories">
{{item | titlecase}}
</option>
</select>
</div>
</div>
</div>
<div class="col-9">
<div class="d-flex flex-wrap" style="height: 400px;">
<div *ngFor="let item of products" class="card m-2 p2"
style="width: 200px;">
<img [src]="item.image" height="150" class="card-img-
top">
<div class="card-header">
<p>{{item.title}}</p>
</div>
</div>
</div>
</div>
</div>
</div>

- Angular Components
- Angular Pipes
- Angular Services

Angular Forms
- Form provides an UI from where user can interact with our
application.
- Angular Forms are classified into 2 types
a) Template Driven Forms
b) Model Driven Forms / Reactive Forms

Template Driven Forms:


- A template driven from uses MVVM architecture.
- The form is configured and handled at UI level.
- All interactions are managed at UI level.
- Template forms are defined by using "ngForm"

<form #frmRegister="ngForm"> </form>

- Form Elements are configured by using "ngModel"

<input type="text"
name="UserName" ngModel #UserName="ngModel">
<select name="City" ngModel #City="ngModel">
</select>

- Every form element comprises following properties

UserName.value - Returns value


UserName.pristine
UserName.dirty
UserName.touched
UserName.untouched
UserName.valid
UserName.invalid
UserName.errors

- It reduces the number of requests to page


- It improves the page load time.
- Heavy on UI
- Interactions will be slow.
- Separation concerns
- Hard to extend
- Hard to test.

Validating Template Driven Forms


==========================
Template Driven Form
- Form and Form Elements are Configured at UI level
- FormsModule is required to configure forms and
elements.
- It is defined in @angular/forms
- "NgForm" is used to define a form
- "NgModel" is used to define a form element.

Syntax:
<form #frmRegister="ngForm">
<input type="text" ngModel name="UserName"
#UserName="ngModel">

</form>

- NgForm provides various properties


value : It returns an object with key and value
collection
Key refers to element name
Value refers to element value

Syntax:
frmRegister.value
{
"UserName:" ",
"Mobile": " "
}

frmRegister.value.UserName
frmRegister.value.Mobile

- Form data is submitted by using


(submit) event
(ngSubmit) event

Ex:
templateform.component.ts

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

@Component({
selector: 'app-templateform',
templateUrl: './templateform.component.html',
styleUrls: ['./templateform.component.css']
})
export class TemplateformComponent implements OnInit
{

constructor() { }

ngOnInit(): void {
}
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}

templateform.component.html

<div class="container-fluid">
<form #frmRegister="ngForm"
(ngSubmit)="FormSubmit(frmRegister.value)">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dd><input name="UserName" ngModel
#UserName="ngModel" type="text"></dd>
<dt>Mobile</dt>
<dd><input type="text" name="Mobile" ngModel
#Mobile="ngModel"></dd>
</dl>
<button type="submit">Register</button>
</form>
<h3>Details</h3>
<dl>
<dt>User Name</dt>
<dd>{{frmRegister.value.UserName}}</dd>
<dt>Mobile</dt>
<dd>{{frmRegister.value.Mobile}}</dd>
</dl>
</div>

Validating Template Driven Form


--------------------------------------------
- Validation is the process of verifying user input.
- Validation is required to ensure that contradictionary
and unauthorized data is not get stored into database.
- Angular can handle validations by using pre-defined
services
- Angular validation services are classified into 2 types
a) Form State Validation Services
b) Input State Validation Services

Form State Validation Services


------------------------------------------
- These are used to verify all fields in the form.
- These are related to <form> element
- It will not report the problem of any specific element, it
uses entire
form state for validation.
- Angular form state validation services are

Service Property Description


---------------------------------------------------------------------------
-----------------
NgPristine pristine Form not
modified
All fields in the form are
untouched.

NgDirty dirty It returns true if any one


form field is modified.

NgValid valid It returns true if all form


fields are valid.
NgInvalid invalid It returns true if any
one
form field is invalid.

NgSubmitted submitted It returns true


when form
is submitted.

Syntax:
frmRegister.pristine
frmRegister.dirty

Note: All validation services are boolean type, they return


true or false.
Angular uses HTML validations
- required
- minlength
- maxlength
- min
- max
- pattern
Ex:
templateform.component.css

.invalid-style {
background-color: rgb(253, 202, 202);
padding: 10px;
}
.valid-style {
background-color: rgb(198, 248, 198);
padding: 10px;
}

templateform.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-templateform',
templateUrl: './templateform.component.html',
styleUrls: ['./templateform.component.css']
})
export class TemplateformComponent implements OnInit
{

constructor() { }

ngOnInit(): void {
}
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}

template.component.html

<div class="container-fluid">
<div class="row mt-3">
<div class="col-5">
<form [ngClass]="{'valid-style':frmRegister.valid,
'invalid-style':frmRegister.invalid}"
#frmRegister="ngForm"
(ngSubmit)="FormSubmit(frmRegister.value)">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dd><input required minlength="4"
maxlength="10" name="UserName" ngModel
#UserName="ngModel" type="text"></dd>
<dt>Mobile</dt>
<dd><input required pattern="\+91[0-9]{10}"
type="text" name="Mobile" ngModel
#Mobile="ngModel"></dd>
</dl>
<button [disabled]="frmRegister.invalid"
type="submit">Register</button>
<button *ngIf="frmRegister.dirty">Save</button>
</form>
</div>
<div class="col-7">
<h2>Validation Services</h2>
<dl>
<dt>Pritine [No Changes Detected]</dt>
<dd>{{frmRegister.pristine}}</dd>
<dt>Dirty [Changes Detected]</dt>
<dd>{{frmRegister.dirty}}</dd>
<dt>Valid [All fields Valid]</dt>
<dd>{{frmRegister.valid}}</dd>
<dt>Invalid [Any one field Invalid]</dt>
<dd>{{frmRegister.invalid}}</dd>
<dt>Submitted</dt>
<dd>{{frmRegister.submitted}}</dd>
</dl>
</div>
</div>
</div>

Input State Validation Services


-----------------------------------------
- Angular provides validation services to verify every field
individually.
- Angular input state services are

Service Property Description


---------------------------------------------------------------------------
------------------
NgPristine pristine Field not modified
NgDirty dirty Field modified
NgValid valid Field have valid data
NgInvalid invalid Field not valid
NgTouched touched Field get focus
NgUnTouched untouched Not in focus
NgErrors errors It is an object for all
html errors.

Syntax:
UserName.pristine
UserName.dirty
Mobile.invalid

- Angular 13 validation object provides the access for


properties using a property reference.

UserName.errors?.required - Before Angular 13


UserName.errors?.['required'] - Angular 13

objectName['Property']

Ex: Form and Input State Validations

templateform.component.html

<div class="container-fluid">
<div class="row mt-3">
<div class="col-5">
<form #frmRegister="ngForm">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dd><input required minlength="4"
name="UserName" ngModel #UserName="ngModel"
type="text"></dd>
<dd class="text-danger"
*ngIf="frmRegister.submitted || (UserName.touched &&
UserName.invalid)">
<span
*ngIf="UserName.errors?.['required']">User Name
Required</span>
<span
*ngIf="UserName.errors?.['minlength']">User Name too
short</span>
</dd>
<dt>Mobile</dt>
<dd><input required
pattern="\+91\d{10}" type="text" name="Mobile"
ngModel #Mobile="ngModel"></dd>
<dd class="text-danger"
*ngIf="frmRegister.submitted || (Mobile.touched &&
Mobile.invalid)">
<span
*ngIf="Mobile.errors?.['required']">Mobile
Required</span>
<span
*ngIf="Mobile.errors?.['pattern']">Invalid Mobile</span>
</dd>
</dl>
<button type="submit">Register</button>
</form>
</div>
<div class="col-7">

</div>
</div>
</div>
Template Forms
=============
Template Validation
a) Form State
pristine
dirty
valid
invalid
submitted
b) Input State
pristine
dirty
valid
invalid
touched
untouched
errors?.['required', 'minlength', 'pattern']

Custom Validations:
---------------------------
- You can write your own validation function and bind to
any HTML element.
- It requires event and property binding.

Ex:
templateform.component.ts

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

@Component({
selector: 'app-templateform',
templateUrl: './templateform.component.html',
styleUrls: ['./templateform.component.css']
})
export class TemplateformComponent implements OnInit
{

constructor() { }

ngOnInit(): void {
}
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}
isCityInValid:boolean = true;
CityChanged(e:any){
if(e.target.value=='-1'){
this.isCityInValid = true;
} else {
this.isCityInValid = false;
}
}
isEvenInvalid:boolean = true;
VerifyEven(e:any){
if(parseInt(e.target.value)%2==0){
this.isEvenInvalid = false;
} else {
this.isEvenInvalid = true;
}
}

templateform.component.html

<div class="container-fluid">
<div class="row mt-3">
<div class="col-5">
<form #frmRegister="ngForm">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dd><input required minlength="4"
name="UserName" ngModel #UserName="ngModel"
type="text"></dd>
<dd class="text-danger"
*ngIf="frmRegister.submitted || (UserName.touched &&
UserName.invalid)">
<span
*ngIf="UserName.errors?.['required']">User Name
Required</span>
<span
*ngIf="UserName.errors?.['minlength']">User Name too
short</span>
</dd>
<dt>Mobile</dt>
<dd><input required
pattern="\+91\d{10}" type="text" name="Mobile"
ngModel #Mobile="ngModel"></dd>
<dd class="text-danger"
*ngIf="frmRegister.submitted || (Mobile.touched &&
Mobile.invalid)">
<span
*ngIf="Mobile.errors?.['required']">Mobile
Required</span>
<span
*ngIf="Mobile.errors?.['pattern']">Invalid Mobile</span>
</dd>
<dt>Your City</dt>
<dd>
<select (change)="CityChanged($event)"
name="City" ngModel #City="ngModel">
<option value="-1">Select Your
City</option>
<option value="Delhi">Delhi</option>
<option value="Hyd">Hyd</option>
</select>
</dd>
<dd *ngIf="isCityInValid" class="text-danger">
<span>Please Select Your City</span>
</dd>
<dt>Veriy Code [Enter Any Even Number]</dt>
<dd>
<input (blur)="VerifyEven($event)"
name="Even" ngModel #Even="ngModel" type="text">
</dd>
<dd class="text-danger" *ngIf="isEvenInvalid">
<span>Code Required - Must be an Even
Number</span>
</dd>
</dl>
<button type="submit">Register</button>
</form>
</div>
<div class="col-7">

</div>
</div>
</div>

Angular Validation CSS Classes


-------------------------------------------
- Angular CSS classes can verify the validation state and
define effects without using class or style binding.

.ng-pristine
.ng-dirty
.ng-valid
.ng-invalid
.ng-touched
.ng-untouched
Syntax:
form.ng-pristine {

}
input.ng-valid {
}
select.ng-dirty {

Ex:
templateform.component.css

input.ng-valid {
border:1px solid green;
box-shadow: 2px 2px 2px green;
}
input.ng-invalid {
border:1px solid red;
box-shadow: 2px 2px 2px red;
}
form.ng-invalid {
background-color: lightpink;
padding: 20px;
}
form.ng-valid {
background-color: lightgreen;
padding: 20px;
}

Draw Backs
----------------
- Tightly coupled
- Hard to Test
- Hard to Extend
- Heavy on UI
- It will reduce the initial load time but response time will
be slow.
- Separation concerns

Model Driven Forms / Reactive Forms


==============================
- It creates and configures a form at controller level.
- Light weight in UI.
- Clean separation of functionality and interface.
- Easy to extend
- Loosely couple
- East to Test
- Dynamically you can add or remove elements.
- If you are designing inline component model driven
forms will be hard to maintain.
- Every element is designed in controller level and
rendered into UI.
- Response time will be fast.
- Angular requires "ReactiveFormsModule" to design
form and elements.
- It is a member of "@angular/forms"
- ReactiveFormsModule provides the classes
FormGroup It is used to configure <form> element
FormControl It is used to configure form elements
FormBuilder It is a service for form and elements.

FormControl:
- It is the base class for all form elements like button,
textbox, checkbox, radio, listbox etc..

- Create a new control


Syntax:
Name = new FormControl('value', validators);
City = new FormControl('CityName', validators);

- Bind to UI elements by using


"formControlName" attribute

<input type="text" formControlName="Name">

Name.value
Name.pristine
Name.dirty etc..

<select forControlName="City"> </select>

Template Form:
<input type="text"
name="Name" ngModel #Name="ngModel">
Model Form:
<input type="text" formControlName="Name">

Angular 13 Reactive Form


------------------------------------
- You have to define a pseudo form for controls.
- You can't define controls directly.
- You need form of pseudo form

<body> Valid
<form>
</form>
<form>
</form>
</body>

<body> Invalid
<form>
<form>
</form>
</form>
</body>

<form>
<div [form]>
</div>
</form>

Model Forms and Form Builder Service


Model Driven - Reactive Forms
- Module ReactiveFormsModule
- Classes
FormGroup
FormControl
FormBuilder
Validators

- FormGroup : It provides set of properties and methods that


are
used to create a <form> element dynamically.

Syntax:
frmRegister = new FormGroup({
// controls
});

You can bind Form Group to any container in HTML by


using "formGroup" property.

Syntax:
<div [formGroup]="frmRegister"> </div>
<form [formGroup]="frmRegister"> </div>

You can access form properties by using form group


reference
Syntax:
frmRegister.value : Returns an object with controls and
values.
frmRegister.pristine
frmRegister.dirty
frmRegister.valid
frmRegister.invalid
frmRegister.submitted

- FormControl : It provides set of properties and methods to


design a form element.

Syntax:
Name : new FormControl('value', [ Validators ]);

You can bind the form control to any form element


by using "formControlName" attribute.

Syntax:
<input type="text" formControlName="Name">
<select forControlName="Name">
<input type="checkbox" formControlName="Name">

Note: Angular 13+ versions will not allow to define a control


outside form group. Every form element must be inside form
group.

Ex:
1. Import "ReactiveFormsModule" in "app.module.ts"

import { ReactiveFormsModule } from '@angular/forms';

imports : [
ReactiveFormsModule
]
- Every ReactiveForm Control is "Async"
- It allows to update of post only specific portion of form.
- It implicitly uses "Ajax".
- FormGroup provide "patchValue()" that can update
asyncrhonously.

Parent Form : [formGroup]


Child Form : formGroupName
Control : formControlName

Syntax:
<form [formGroup]="ParentForm">
<input type="text" formControlName="Name">
<div formGroupName="ChildForm">
<input type="text" formControlName="Price">
</div>
</form>

Ex:
modelform.component.ts

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


import { FormControl, FormGroup } from '@angular/forms';

@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
export class ModelformComponent implements OnInit {

frmRegister = new FormGroup({


Name: new FormControl(''),
Price: new FormControl(0),
frmStock: new FormGroup({
Status : new FormControl(true),
City : new FormControl('')
})
})

constructor() { }

ngOnInit(): void {

}
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}
UpdatePartial(){
this.frmRegister.patchValue({
Name: 'Samsung TV',
frmStock: {
City: 'Hyd'
}
})
}

modelform.component.html

<div class="container-fluid">
<form [formGroup]="frmRegister"
(submit)="FormSubmit(frmRegister.value)" class="bg-warning
p-3 w-75">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dd><input formControlName="Name"
type="text"></dd>
<dt>Price</dt>
<dd><input type="text"
formControlName="Price"></dd>
<div formGroupName="frmStock" class="bg-info p-3
w-25">
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dd><input type="checkbox"
formControlName="Status"> Available</dd>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
<button (click)="UpdatePartial()" type="button">Update
Partial</button>
</form>
</div>

Note: Allocating memory for control every time will overload


memory.
It is good for discreet operations, but not for continous
operations

You can design a form with continous memory without


disconnected access by using a service "FormBuilder".
FormBuilder
==========
- FormBuilder is a service.
- Service uses a single ton pattern.
- Memory is allocated for the first request and the same
memory will be used across all requests.
- Every control can use the form memory.
- FormBuilder provides following methods
a) group() : It configures <form>
b) control() : It configures form element
c) array() : It is a collection of controls

Syntax:
frmRegister:any;

constructor(private fb: FormBuilder) { }

ngOnInit() {
this.frmRegister = this.fb.group({
Name: this.fb.control(''),
frmStock: this.fb.group({
Status: this.fb.control(true)
})
})
}

Note: Binding form builder with UI is same as FormGroup and


FormControl.

Ex:
modelform.component.ts

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


import { FormControl, FormGroup, FormBuilder } from
'@angular/forms';
@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
export class ModelformComponent implements OnInit {

constructor(private fb: FormBuilder) { }

frmRegister:any;

ngOnInit(): void {
this.frmRegister = this.fb.group({
Name: this.fb.control(''),
Price: this.fb.control(0),
frmStock: this.fb.group({
Status: this.fb.control(true),
City: this.fb.control('Delhi')
})
})
}
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}
UpdatePartial(){
this.frmRegister.patchValue({
Name: 'Samsung TV',
frmStock: {
City: 'Hyd'
}
})
}
}

modelform.component.html

<div class="container-fluid">
<form [formGroup]="frmRegister"
(submit)="FormSubmit(frmRegister.value)" class="bg-warning
p-3 w-75">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dd><input formControlName="Name"
type="text"></dd>
<dt>Price</dt>
<dd><input type="text"
formControlName="Price"></dd>
<div formGroupName="frmStock" class="bg-info p-3
w-25">
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dd><input type="checkbox"
formControlName="Status"> Available</dd>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
<button (click)="UpdatePartial()" type="button">Update
Partial</button>
</form>
</div>

Form Array [ array() ]


------------------------------
- It is a collection of controls.
- It allows to dynamically change the form by adding and
removing controls.

Ex:

modelform.component.ts

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


import { FormControl, FormGroup, FormBuilder, FormArray }
from '@angular/forms';

@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
export class ModelformComponent implements OnInit {

constructor(private fb: FormBuilder) { }

frmRegister:any;

ngOnInit(): void {
this.frmRegister = this.fb.group({
Name: this.fb.control(''),
Price: this.fb.control(0),
frmStock: this.fb.group({
Status: this.fb.control(true),
City: this.fb.control('Delhi')
}),
newControls: this.fb.array([this.fb.control('')])
})
}

get NewControls(){
return this.frmRegister.get('newControls') as FormArray;
}
AddClick(){
this.NewControls.push(this.fb.control(''));
}
RemoveClick(i:number){
this.NewControls.removeAt(i);
}

FormSubmit(obj:any){
alert(JSON.stringify(obj));
}
UpdatePartial(){
this.frmRegister.patchValue({
Name: 'Samsung TV',
frmStock: {
City: 'Hyd'
}
})
}

modelform.component.html
<div class="container-fluid">
<form [formGroup]="frmRegister"
(submit)="FormSubmit(frmRegister.value)" class="bg-warning
p-3 w-75">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dd><input formControlName="Name"
type="text"></dd>
<dt>Price</dt>
<dd><input type="text"
formControlName="Price"></dd>
<dt>Upload Photo <button type="button"
(click)="AddClick()" class="btn btn-link">Add
More</button></dt>
<dd *ngFor="let item of NewControls.controls; let
i=index">
<input type="file" name="i">
<button (click)="RemoveClick(i)" class="btn btn-
link">Remove</button>
</dd>
<div formGroupName="frmStock" class="bg-info p-3
w-25">
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dd><input type="checkbox"
formControlName="Status"> Available</dd>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
<button (click)="UpdatePartial()" type="button">Update
Partial</button>
</form>
</div>

Validation in Reactive Forms and Routing


Reactive Forms
- FormGroup
- FormControl
- FormBuilder
control()
group()
array()
Validation in Reactive Forms
======================
- Template forms require validation attributes defined at UI
level.

Syntax:
<input type="text" required minlength="4" pattern="">

- Reactive Forms validation is defined at controller level.


- Validations are configured by using "Validators" class.
- Validators class will provide the properties for validating
input elements.

Syntax:
new FormControl('value', [Validators.required]);

control('value', [Validators.required]);

- Validation properties are defined in controller, however the


validation messages are configured in UI.

Syntax:
this.frmRegister = fb.group({
Name: fb.control(' ', [Validators.required,
Validators.minlength(4)])
})

get Name() {
retrun this.frmRegister.get('Name') as FormControl;
}

<input type="text" formControlName="Name">


<div *ngIf="Name.touched && Name.invalid">
<span *ngIf="Name.errors?.['required']"> Name Required
</span>
<span *ngIf="Name.errors?.['minlength']"> Name too
short </span>
</div>

Note: Every element in form requires an Accessor, if you are


using a Form Builder. [getter]

Summary - Angular Forms:


1. Template Driven
2. Model Driven
3. Template Driven by using
ngModel
ngForm
4. Validating Template Forms
- Form State Validation Services
- Input State Validation Services
- Validation CSS classes
5. Reactive Forms
- FormGroup
- FormControl
- FormBuilder
a) group()
b) control()
c) array()
- Validators

Ex:
modelform.component.ts

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


import { FormControl, FormGroup, FormBuilder, FormArray,
Validators } from '@angular/forms';

@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
export class ModelformComponent implements OnInit {

constructor(private fb: FormBuilder) { }

frmRegister:any;

ngOnInit(): void {
this.frmRegister = this.fb.group({
Name: this.fb.control('',[Validators.required,
Validators.minLength(4)]),
Price: this.fb.control(0),
frmStock: this.fb.group({
Status: this.fb.control(true),
City: this.fb.control('Delhi')
}),
newControls: this.fb.array([this.fb.control('')])
})
}

get Name() {
return this.frmRegister.get('Name') as FormControl;
}

get NewControls(){
return this.frmRegister.get('newControls') as FormArray;
}
AddClick(){
this.NewControls.push(this.fb.control(''));
}
RemoveClick(i:number){
this.NewControls.removeAt(i);
}

FormSubmit(obj:any){
alert(JSON.stringify(obj));
}
UpdatePartial(){
this.frmRegister.patchValue({
Name: 'Samsung TV',
frmStock: {
City: 'Hyd'
}
})
}

modelform.component.html
<div class="container-fluid">
<form [formGroup]="frmRegister"
(submit)="FormSubmit(frmRegister.value)" class="p-3 w-75">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dd><input formControlName="Name"
type="text"></dd>
<dd class="text-danger" *ngIf="Name.touched &&
Name.invalid">
<span *ngIf="Name.errors?.['required']">Name
Required</span>
<span *ngIf="Name.errors?.['minlength']">Name too
short.. min 4 chars</span>
</dd>
<dt>Price</dt>
<dd><input type="text"
formControlName="Price"></dd>
<dt>Upload Photo <button type="button"
(click)="AddClick()" class="btn btn-link">Add
More</button></dt>
<dd *ngFor="let item of NewControls.controls; let
i=index">
<input type="file" name="i">
<button (click)="RemoveClick(i)" class="btn btn-
link">Remove</button>
</dd>
<div formGroupName="frmStock" class="bg-info p-3
w-25">
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dd><input type="checkbox"
formControlName="Status"> Available</dd>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
<button (click)="UpdatePartial()" type="button">Update
Partial</button>
</form>
</div>

Angular Routing
----------------------
- Web Applications follow various techniques in building
application
a) Model Binding
b) Data Binding
c) Event Binding
d) Style Binding
e) Caching
f) Routing etc..

- Routing is a technique used in web applications for


configuring SEO and User Friendly URL's.

Ex: Without routing

http://www.amazon.in/electronics.jsp?category=mobiles
HYPERLINK
"http://www.amazon.in/electronics.jsp?category=mobiles&bran
d=samsung&minPrice=10000"& HYPERLINK
"http://www.amazon.in/electronics.jsp?category=mobiles&bran
d=samsung&minPrice=10000"brand=samsung HYPERLINK
"http://www.amazon.in/electronics.jsp?category=mobiles&bran
d=samsung&minPrice=10000"& HYPERLINK
"http://www.amazon.in/electronics.jsp?category=mobiles&bran
d=samsung&minPrice=10000"minPrice=10000

With routing

http://www.amazon.in/electronics/mobiles/samsung/10000

- SEO friendly URL's can find exact location of topic and


recommend later.
- User friendly URL's allow to query any content directly from
URL.
- Routing allow "ad-hoc" queries [live queries].
- Routing uses Ajax calls, without reloading the complete page
it can add new content to page.
- In Single Page Applciations [SPA], user can stay on one
page and can access everything from the page.
- Routing can be configured
a) Client Side
b) Server Side
- Angular is using routing client side

Server Side:
fakestoreapi.com/products?id=2
fakestoreapi.com/products/2
Route and Route Parameters
Angular Routing
----------------------
- The classes required for configuring routes
- RouterModule
- Routes
- These are defined in "@angular/router"
- "RouterModule" provides set of properties and methods to
export and import routes for application.
- "Routes" is used to configure RouteTable, which comprises
of collection of routes.

Adding Route for Application:


---------------------------------------
- You can choose routing module while creating a new
application.
(or)
- You can manually add "routing module"

Ex:
1. Create a new application in workspace

> ng generate application flipkart


2. Add routing module ? No

3. Which Style Sheet Format ? CSS

4. Go to "App" folder and add a new file

"app-routing.module.ts"

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


import { RouterModule, Routes } from '@angular/router';

const routes : Routes = [ ];

@NgModule({
imports : [RouterModule.forRoot(routes)],
exports : [RouterModule]
})

export class AppRoutingModule { }

5. Register the Modules in "app-module.ts"

imports: [
BrowserModule,
AppRoutingModule,
RouterModule
],

Build Routes for Application


-------------------------------------
- Routes are defined in a RouteCollection
- Every route initially comprises 2 basic attributes
a) path
b) component
- "path" defines how the component is requested
- "component" defines the component class to load and
render.

Syntax:

const routes: Routes = [


{ path: 'home', component: HomeComponent }
]

- Path configuration contains wild card routes

{ path : '/' } Indicates the component to load when


the application is requested. [Server Side]

It specifies the default path to render.

{ path: ' ' } Client Side default path.

{ path: '**' } Indicates the component to load when


requested path not found.

- Setup Startup component for appication


- In startup component you have to design Navigation
[AppComponent is the default startup component]

- Design Navigation in
"app.component.html"
- Routing comprises of 2 elements in page

a) <router-outlet>
b) routerLink

- <router-outlet> defines where to render the result.


- routerLink defines navigation to specific route path.
Ex:
1. Add Components
> ng g c home
> ng g c categories
> ng g c notfound

2. home.component.html

<h2>Flipkart | Home </h2>


<p>Shopping Online - 50% OFF on Electronics</p>

3. categories.component.ts

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

@Component({
selector: 'app-categories',
templateUrl: './categories.component.html',
styleUrls: ['./categories.component.css']
})
export class CategoriesComponent implements OnInit {

categories:any[] = [];
constructor() { }

ngOnInit(): void {
fetch('http://fakestoreapi.com/products/categories
HYPERLINK "http://fakestoreapi.com/products/categories&"&
HYPERLINK
"http://fakestoreapi.com/products/categories&"#39;)
.then(response=>response.json())
.then(data=> {
this.categories = data;
})
}
}

4. categories.component.html

<h2>Categories</h2>
<ol>
<li *ngFor="let item of categories">
{{item|titlecase}}
</li>
</ol>

5. notfound.component.ts

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

@Component({
selector: 'app-notfound',
templateUrl: './notfound.component.html',
styleUrls: ['./notfound.component.css']
})
export class NotfoundComponent implements OnInit {

location:any;
constructor() { }

ngOnInit(): void {
this.location = location.pathname;
}

6. notfound.component.html

<h2>Not Found</h2>
<p>Page you requested <code>{{location}}</code> - Not
Found</p>
7. Go to "app.component.html"

<div class="container-fluid">
<header class="bg-danger text-white text-center mt-2">
<h1><span class="bi bi-cart2"></span> Flipkart
Shopping</h1>
</header>
<section>
<div class="row">
<div class="col-3">
<ul class="list-unstyled">
<li class="mb-3"><a class="btn btn-danger w-100"
routerLink="home">Home</a></li>
<li class="mb-3"><a class="btn btn-danger w-100"
routerLink="categories">Categories</a></li>
</ul>
</div>
<div class="col-9">
<router-outlet></router-outlet>
</div>
</div>
</section>
</div>

8. Go to "app-routing.module.ts"

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


import { RouterModule, Routes } from '@angular/router';
import { CategoriesComponent } from
'./components/categories/categories.component';
import { HomeComponent } from
'./components/home/home.component';
import { NotfoundComponent } from
'./components/notfound/notfound.component';
const routes :Routes = [
{path: 'home', component: HomeComponent},
{path: 'categories', component: CategoriesComponent},
{path: ' ', redirectTo: 'home', pathMatch: 'full' },
{path: '**', component: NotfoundComponent}
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

Route Parameters
==============
- A route parameter allows to store data in URL and transfer
across components in routing.
- Route parameter allows to query any content directly from
URL.
- Route is defined with parameters by using path

{ path: 'home/:param1/:param2/:param3..' }

- To access and use the route parameter you need


"ActivatedRoute" service.

param1: value - Map


.get()
Route Parameter and Child Routes
Route Parameter
- It allows to query any content directly from URL.
- It allows to transport data from one component to another.
- Route parameter is configured in route path
Syntax:
{ path: 'details/:id/:name', component : DetailsComponent
}

- Route parameter values are passed in the URL

Syntax:
http://localhost:4200/details/1/Mobile

- You can access and use route parameters in any component


by using "ActivatedRoute" service.

Syntax:
constructor(private route: ActivatedRoute) { }

ProductId:any;
Name:any;

ngOnInit() {
this.ProductId = this.route.snapshot.paramMap.get("id");
}

snapshot : It is used to access any specific portion of


route.
paramMap : Parameters Map, which is a key and value
collection. [Key = Parameter , Value = Value]
Configuring Child Routes:
----------------------------------
- A route path can have another component to display within
the context by using "children".

Syntax:
{ path: 'parent', component : ParentComponent,
children: [
{path: 'child', component: ChildComponent }
]
}

- The child component is displayed in the parent component


by using "router-outlet".

<parentcomponent>
details
<router-outlet> </router-outlet>
</parentcomponent>
Routing Complete Example - ZIP
for Flipkart Example.

End to End Application Design with MEAN Stack


MEAN Stack Application

- MongoDB Database
- Express Middleware
- Angular Front End
- Node Server Side - API

Database
1. Download and Install MongoDB database on your PC

https://www.mongodb.com/try/download/community

Version : 5.0.6 (current)


OS : windows
Package : MSI

2. While Installing MongoDB, It will prompt for "MongoDB


Compass"
You have to select "MongoDB Compass".

3. Open MongoDB Compass on your PC

4. Click "Connect" button to connect with Database Server

[If server is not running then manually start server]


- open "services.msc"
- right click on "mongodb server"
- select start

5. MongoDB Terminology

RDBMS MongoDB
------------------------------------------------------
Database Database
Table Collection
Records Document
Field Field
Joins Embedded Documents

Every document [Record] is JSON Type

6. Create a new Database


- Click Create Database Button
- Specify following details

Database Name : demodb


Collection Name : tblusers

7. Open Database "demodb"

8. Open Collection "tblusers"


9. Select "Add Data --> Insert Document"

{
"UserId": "john_nit",
"UserName": "John",
"Password": "john@12",
"Age": 22,
"Email": "john@gmail.com",
"Mobile": "+919876543210"
}
10. Click Insert

Summary:
Database Name : demodb
Table Name [Collection] : tblusers
Connection String : mongodb://127.0.0.1:27017

"www.connectionstrings.com&quot;

Server Side API


----------------------
We will use
- Node.js Server Side Scripting
- Express Create API
1. Go to your Angular Workspace

2. Open Angular Workspace in VS Code.

3. Add a new folder into workspace by name "server".

4. Install the following packages

> npm install express --save [middleware]


> npm install mongodb --save [database driver]
> npm install cors --save [CORS Issues]

5. Node.js Server Side Application is configure by using


JavaScript file

6. Add a new JavaScript file into "server" folder by name


"index.js"

var express = require("express");


var cors = require("cors");
var mongoClient = require("mongodb").MongoClient;

var connectionString = "mongodb://127.0.0.1:27017";


var app = express();
app.use(cors());
app.use(express.urlencoded({
extended: true
}));
app.use(express.json());

app.get("/getusers", function(request, response){


mongoClient.connect(connectionString, function(err,
clientObject){
if(!err){
var dbo = clientObject.db("demodb");
dbo.collection("tblusers").find().toArray(function(err,
documents){
if(!err){
response.send(documents);
}
})
}
})
});
app.post("/registeruser", function(request, response){
var data = {
"UserId": request.body.UserId,
"UserName": request.body.UserName,
"Password": request.body.Password,
"Age": parseInt(request.body.Age),
"Email": request.body.Email,
"Mobile": request.body.Mobile
};
mongoClient.connect(connectionString, function(err,
clientObject){
if(!err){
var dbo = clientObject.db("demodb");
dbo.collection("tblusers").insertOne(data,
function(err, result){
if(!err) {
console.log("Record Inserted");
}
})
}
})
})

app.listen(8080);
console.log("Server Started : http://127.0.0.1:8080");
Route Guard and Cookie
Route Guards
- Allows to configure access restriction for any specific route
path in application.
- Route Guards are configured at various levels, like
a) To Activate a route
b) To exit a route
c) To exit a child route etc..
- These route phases are reffered as "Route Cycle Hooks"

(a) CanActivate : activate route


(b) CanActivateChild : activate child route
(c) CanDeactivate : to exit the route
(d) CanLoad : load component on success

- Route Cycle hook methods are implemented from interfaces,


which means every route guard can handle all hook methods.

- All route cycle methods are boolean type: true or false.


- Route is a accessible only when hook method returns true.
- You can restrict access to route by returning false.

>npm install ngx-cookie-service --save


get()
set()
getAll()
delete()
deleteAll()

Lazy Routes
Deployment
Testing
Lazy Routes and Testing
Lazy Routes
- Lazy loading is a software design pattern that allows to load
only the content that is requested.
- Eager Loading loads the modules and library even when you
are not using them.
- It improves the performance of application.
- Application specific framework.
- Light weight application.

FAQ: How to configure lazy route?


Ans: Lazy routes are configure by using
"loadChildren"

Syntax:
{ path : 'register' component: RegisterComponent }

{ path : 'register' loadChildren: () =>


import('moduleName').then(module=> module.ModuleName) }

Note: Angular can implement lazy loading for routes when you
configure application with various modules.

FAQ: Can Angular application have multiple route modules?


Ans: Yes. If you are configuring application at module level

FAQ: Can angular application have multiple "app.module.ts"?


Ans: Yes

Ex:
1. Create new Application

> ng generate application hdfcbank

2. Add modules into application

> ng generate module personal --route personal --module


app.module

> ng generate module nri --route nri --module app.module

3. Go to app.component.html

<div>
<a routerLink="personal">Personal Banking</a>
<span>|</span>
<a routerLink="nri">NRI</a>
<span>|</span>
<a routerLink="agri">AGRI-Govt.India</a>
</div>
<div style="margin-bottom: 20px;">
<router-outlet></router-outlet>
</div>

Ex: Configure Lazy Route for Component

const routes: Routes = [


{ path: '', loadChildren:()=>
import('./nri.component').then(component=>
component.NriComponent) }
];

Angular Unit Testing


----------------------------
- It is the process of testing every component, service or pipe
and ensure that they are matching the requirements.
- Angular implicitly configured with a testing framework
"Jasmine - Karma"
- Jasmine uses various methods for testing functions.
- It comprises of 3 phases
a) Arrange
b) Act
c) Assert
- Arrange is the process of importing the module or
component test.
- Act defines the functionality to test.
- Asserts verifies the result returned and the result expected

return result = expected : Test Pass


return result != expected : Test Fail

- Test Methods

describe()
expect()
toBe(),
toBeTruthy()
toBeEqual()

Ex: Add a new component "HomeComponent"

> ng g c home

home.component.ts

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

@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}
CalculateTotal(qty:number, price:number){
return qty * price;
}
Title(str:string) {
return str;
}
}

home.component.spec.ts

describe('HomeComponentTest', function(){
it('Total Test', function(){
expect(component.CalculateTotal(2,4000)).toBe(12000);
})
it('Title Test', function(){
expect(component.Title('HDFC Home')).toBe('HDFC
Home');
})
})

> ng test --project=hdfcbank

Build and Deployment

- Building is the process of checking


a) Syntactical errors
b) Dependencies
c) Directives
d) Meta data
- After checking trans compiling typescript into javascript.
- Copying all files into "dist" - output directory
- "Dist" is a folder ready for deployment [Production - Go Live].
- You can use the following commands for building

> ng build [dist]


> ng build outputPath=folderName [you can change dist]
> ng build baseHref=http://localhost:8080
> ng build --index=login

- You can deploy angular application in


a) Local Servers
IIS
XAMPP
WAMP
MAMP etc..
b) Cloud Servers
Firebase
Azure
GitHub Pages
AWS
Now
Netify etc..

> ng serve --project=shopping [ local server ]

Ex: Deploying Angular Application on Firebase

1. Create a new project on firebase

https://firebase.google.com/

2. Login with your Google Account

3. Go to Firebase "Console"

Step-1:
- Click "Create New Project"
- Specify Name for project

"angular-fakeshop"

Step-2:
- Select Cloud Services
- Enable Analytics

Step-3
- Select Account
- Default Firebase Account

- Project is Created successfully.

4. Download and Install Firebase tools on your PC

C:\> npm install -g firebase-tools

5. Login into firebase tools from your PC

C:\>firebase login

6. Open your angular project and build for production (go live)

>ng build --project=flipkart [ Angular 13]


>ng build --project=flipkart --prod

This will compile, check for dependencies, convert typescript


into javascript and then copy all file into output directory "dist".

✔ Browser application bundle generation complete.


[supporting files - dynamic]
✔ Copying assets complete.
[resources - static]
✔ Index html generation complete.
[startup page]

7. You need cloud library in Angular project in order to deploy


on cloud.
Every cloud have a different library for angular.
The firebase library for angular is

> ng add @angular/fire --project=flipkart


> which feature you want to setup
ng deploy -- hosting
> which google account to use
> which domain to deploy - hosting site

https://angular-fakeshop.web.app

8. Deploy Angular project on cloud


> ng deploy --project=flipkart

[it will copy all files and folders of 'dist' into cloud]

Domain:
https://angular-fakeshop.firebaseapp.com/home

You might also like