Angular 13@ Sudhakar Sharma899
Angular 13@ Sudhakar Sharma899
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.
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’}}
Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};
{{ product.Price | currency: ‘INR’ }}
{{ product.Price | currency: ‘₹’ }}
DatePipe date It is used for displaying date and time value in various date and
time formats.
Ex:
product = {
Name: 'JBL Speaker',
Price: 4500.50,
Mfd: new Date('2020/02/10')
};
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.
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 = [ ]
Angular Services
14/02/22 Setup Environment for TypeScript
https://nodejs.org/en/
[Windows 8+, any another OS]
C:\>node -v 12+
C:\>npm -v 6+
https://code.visualstudio.com/
D:\TypeScript-Project
<!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>
15/02/22
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
Syntax:
let username:string | number;
username = "john"; // valid
username = 1001; // valid
username = true; // invalid
Ex:
1. Write the following code into "Index.ts"
console.log(`Name=${ProductName}\nPrice=${Price}\nStock=${(Stock==true)?'Available':'Out of Stock'}`);
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();
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
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.
Syntax:
let collection:any[] = new Array();
collection[0] = 10;
collection[1] = 'john'; /// valid
Syntax:
let collection:string[] | number[] = [10, 'john']; // invalid
Syntax:
let collection: any[] = [ ];
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
16/02/22
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.Stock}\nQty=${this.Qty}\nTotal=$
{this.Total()}\nShippedTo=${this.ShippedTo}`);
}
}
product.Print();
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}`);
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));
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));
Syntax:
let dateofBirth:any = new Date('yy-mm-dd');
getHours()
getMinutes()
getSeconds()
getMilliSeconds()
getDay()
getDate()
getMonth()
getFullYear()
Ex:
let Manufactured:any = new Date('2022-01-18');
console.log(`Manufactured Year=${Manufactured.getFullYear()}`);
Syntax:
let regExp:any = /[A-Z]{4,10}/;
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 = / /;
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
}
Ex:
interface ProductContract
{
Id:number;
Name:string;
Cost:number;
Stock:boolean;
}
let product:ProductContract = {
"Name": "Samsung TV",
"Cost": 56000.44,
"Stock": true,
"Id": 1,
}
17/02/22
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,
}
Ex:
interface ProductContract
{
Id:number;
Name:string;
Cost:number;
Stock?:boolean; // optional
}
let product:ProductContract = {
"Name": "Samsung TV",
"Cost": 56000.44,
"Id": 1,
}
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}`);
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.Qty}\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
interface A
{
}
interface B extends A
{
}
interface C extends B
{
}
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'
}
18/02/22
Contracts in OOP
- rules
- optional rules
- readonly rules
- extend contracts
- single, multiple and multilevel
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
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.Stock}`);
}
}
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.
class Base
{
constructor(){
}
}
class Derived extends Base
{
constructor() {
super();
}
}
Template in OOP
=============
- Abstract class
19/02/22
Templates in OOP
- A template comprises of sample data and logic, which you can implement and customize according to the requirements.
Syntax:
interface IName
{
}
class className impements IName
{
}
- A template may contain members defined with functionality as well as the members need to be implemented.
- 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 --------------------------
Module System
=============
- Export
- Default
- Import
CommonJS
Require JS
UMD
AMD
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
Dependency Injection
=================
21/2/22
Generics
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
}
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));
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:27017'});
console.log(`---------Connection to SqlServer-----`);
Syntax:
Method<T>(param:T) { }
Method<IProduct[]>([]);
Syntax:
class Name<T>
{
Property:T;
Method():T { }
}
Ex:
class Factory<T>
{
public FirstName:T|undefined;
public LastName:T|undefined;
}
Enums - Enumeration
22/02/22
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
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
Ex:
enum Route
{
Electronics, // 0
Home = 'http://localhost/app/home' ;,
Contact = 'http://127.0.0.1/app/contact?address' ;,
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.
Ex:
enum Calculate {
A = 10,
B = 20,
C = A + B,
D
}
console.log(`D=${Calculate.D}`);
Syntax:
let name = EnumName[value];
Ex:
enum StatusCode
{
NotFound = 404,
}
let ErrorCode = StatusCode[StatusCode.NotFound];
console.log(`Error Reference: ${ErrorCode}`);
console.log(`Error Code: ${StatusCode.NotFound}`);
Syntax:
enum HttpVerbs
{
GET = 'Fetch Data',
POST = 'Submit Data',
PUT = 'Modify Data'
}
let obj = 'GET' as HttpVerbs;
obj:HttpVerbs;
Namespace
==========
- A namespace is a collection of contracts, templates and components.
- It reduces complexity in module system.
- Namespace using aliasing which is used for importing and refering the library.
Syntax:
declare let x:number = 10; //invalid
declare let x:number; //valid
x=10;
FAQ: What is the purpose of “default”?
-You can export many components from a file.
-Default is used to restrict any one component for exporting. When you try import without using “{ }”.
-Default component can’t be imported by using “{}”
-Every file can have multiple default components. Developer can import any one there is no priority for components.
Note: Every component marked with export can be imported. But not as default import.
Default import is defined without “{ }”.
Ex:
ProjectContracts.ts
export default interface ICategory
{
CategoryId:number;
}
export default interface IProduct
{
Name:string;
Price:number;
}
App.ts
import ICategory from './ProjectContracts'; // valid
import IProduct from './ProjectContracts'; // valid
import { ICategory} from './ProjectContracts'; // invalid
import {ICategory,IProduct} from './ProjectContracts'; // invalid
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:
1.Add a new folder
Project
2.Add following folders into project folder
- Contracts
- Templates
- Services
- App
3.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;
}
}
}
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()}`);
}
}
}
}
MyApp.ts
Compile
> tsc --outFile myapp.js myapp.ts
23/02/22
Classroom LogoClassroom
Hi SUNDAY,
Sudhakar Sharma posted a new material in ANG1302212022 Angular 13 - 7:30 AM.
NEW MATERIAL
DI and Angular
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.
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.
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
}
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.
24/02/22
2. Clear Cache
www.editorconfig.org
D:\my-angular-workspace>
4. This will add "Projects" folder into workspace, which contains your project => "Shopping"
http://localhost:4200
25/02/22
- Create Workspace
- Create Application
- To start application
http://localhost:4200
Resources of "app"
===============
1. Angular Framework comprises
- Modules
- Components
- Services
- Factories
- Templates
- Pipes
- Routing
- State Management [Client Side]
26/02/22
Components in Angular
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
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.
a) selector
b) template
c) styles
Syntax:
template: `<markup> {{ expression }}</markup>`
Syntax:
styles: ['selector{attribute:value}']
@NgModule( {
declarations : [ ComponentName ]
})
@NgModule({
bootstrap: [ ComponentName ]
})
<body>
<app-home> </app-home>
</body>
Ex:
1. Add a new folder by name "components" into "app" folder
@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"
declarations: [
HomeComponent
],
bootstrap: [HomeComponent]
4. Go to Index.html
<body>
<app-home> </app-home>
</body>
27/02/22
* 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;
}
<app-register> </app-register>
@import '../../../node_modules/bootstrap/dist/css/bootstrap.css';
@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>
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.
Ex:
> ng generate component electronics --skip-tests --inline-style --inline-template
Multiple Components
================
1. Add Netflix folder in "app"
2. Generate Components
.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
.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>
28/02/22
Data Binding
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.
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'
}
01/03/22
Interpolation:
==========
- It is the process of rendering data into UI elements as Literal content.
- It is managed by using data binding expression "{{ }}"
Syntax:
product:any = {
Name: 'Samsung TV'
}
<dd>{{product.Name}}</dd>
- It is not good for binding a dynamic value to any property of HTML element.
product:any = {
Stock: true
}
Property Binding
=============
- You can access any HTML element property using property binding entity "[ ]" and bind the dynamic value.
Syntax:
product:any = {
Stock : true
}
- 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;
Note: Table element is not having height as property, It is only available as attribute.
[height]="height" // invalid
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
@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
- ngModel uses both property and event binding to handle two way binding
[(ngModel)] = "dynamicValue"
Ex:
1. Go to "app.module.ts"
imports: [
FormsModule
]
2. data.component.ts
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>
02/03/22
MVVM Architecture
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.
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
@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>
04/03/22
Angular Directives
===============
Directives in Angular
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
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="" >
Syntax:
<dd *ngIf="false">
<img [src]="" width="" height="">
</dd>
Ex:
ifdemo.component.ts
@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>
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>
<ng-template #name>
</ng-template>
05/03/22
"Content Projection"
Content Projection
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:
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
@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>
Content Projection
-------------------------
- Content Projection is a technique where templates are configured explicitly and rendered into component according to
state and situation.
- The process of creating explicit templates and injecting into View is known as "Content Projection".
Syntax:
thenBlock1 : TemplateRef<any>;
- @ViewChild() can identify template type reference in memory and render it into the View. [Provider - Injector]
- A single "then" block in condition can map to multiple templates and render using "Content Projection".
Ex:
ifdemo.component.ts
@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;
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>
07/03/22
ifdemo.component.ts
@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;
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.RatingTemplate:
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"> « </button>
<button (click)="NextClick()" class="btn btn-warning"> » </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;
}
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.
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>
switchdemo.component.ts
@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>
https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=DEMO_KEY
Present
- Image Preview
- Rover Name
- Camera Name
- Date taken
08/03/22
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);
</ol>
<select>
</select>
</body>
Angular:
- It uses "ngFor" to create element dynamically and repeat according to iterator.
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
@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')
.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.
<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>
Ex:
fordemo.component.ts
@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>
fordemo.component.ts
@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=DEMO_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>
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
09/3/22
NgFor Properties
NgFor Properties
==============
Syntax:
<li *ngFor="let item of collection; let i=index; let e=even">
Ex:
indexdemo.component.ts
@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);
}
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>
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
10/03/22
Attribute Directives
Attribute Directives
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.
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
.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
}
- 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
@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
}
}
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.
Syntax: MVC
Syntax: MVVM
Event Binding
Angular Directives
- Component Directives
- Structrual Directives
- Attribute Directives
Data Binding
Style Binding
Class Binding
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..
Syntax:
<button onclick="ButtonClick(this, event)">
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
@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 provides "ngSubmit" for form submit, however you also use "submit" of javascript.
<form (submit)="SubmitClick()">
<form (ngSubmit)="SubmitClick()">
Syntax:
<form #refName="ngForm">
<form #frmRegister="ngForm">
SubmitClick(formObject:any)
{
alert(JSON.stringfy(formObject));
}
12/03/22
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/jewelery
[returns all products belong to specific category]
@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')
.then(response=> response.json())
.then(data=> {
data.unshift("all");
this.categories = data;
})
}
products:any[] = [];
GetProducts(){
fetch('http://fakestoreapi.com/products')
.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>
13/03/22
Custom Events
Custom Events
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.
Syntax:
@Input() Property:DataType = Value;
Ex:
1. Add 2 components
> ng g c parent
> ng g c child
2. child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
ngOnInit(): void {
}
3. child.component.html
4. parent.component.ts
@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>
Syntax:
CustomEvent:EventEmitter<any> = new EventEmitter<any>();
Syntax:
@Output() CustomEvent:EventEmitter<any> = ....
Syntax:
onSendClick() {
this.CustomEvent.emit(value | object);
}
Method(e:any)
{
e.value|object_property
}
Ex:
1. child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
ngOnInit(): void {
}
SendClick(){
this.ChildComponentClick.emit(this.messageToParent);
this.ChildComponentSendObjectClick.emit(this.product);
}
}
2. child.component.html
3. parent.component.ts
@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>
14/03/22
2. filter.component.ts
@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;
constructor() { }
ngOnInit(): void {
}
FilterButtonClick(e:any){
this.FilterChanged.emit(e.target.name);
}
3. filter.component.html
4. products.component.ts
@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')
.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.categoryName}`)
.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>
15/03/22
- 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.
PreviousValue = undefined
CurrentValue = John
- ngOnChanges manages
a) Property Binding
b) Event Binding
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.
16/03/22
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.
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.
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 {
ngOnInit(): void {
}
3. child.component.html
@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>
17/03/22
Angular Material
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
oKnow your component module name
oKnow the dependencies for required module
oKnow the selector for component
oKnow the properties and methods for component
Syntax:
<mat-form-field appearance=”legacy | standard | fill | outline”>
</mat-form-field>
@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
oMatDatepickerModule
oMatNativeDateModule
-Selectors
omat-datepicker-toggle
omat-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]
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>
22/03/22
imports: [
MatDatepickerModule
]
imports: [
MatDatepickerModule,
MatNativeDateModule
]
<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>
Material CDK
==========
- It provides behaviour for components.
- It is Component Development Kit
Ex: Lazy Loading
*ngFor : Eager loading
*ngVirtualFor : Lazy Loading
<cdk-virtual-scroll>
23/03/22
Angular Animations
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
@keyframes name
{
from { }
to { }
}
p{
animation-name: keyframeName
}
@Component(
{
selector: 'app-login',
templateUrl: 'htmlPage',
stylesUrl: [ 'stylesheet' ],
animations: [ ]
}
)
state('initial=>final') state('void=>*')
state('final=>initial') state('*=>void')
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
@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>
<img (mouseover)="ZoomInClick()" (mouseout)="ZoomOutClick()" [@zoom]="animationState"
src="assets/shoe.jpg" width="100" height="100">
</div>
</div>
</div>
component.ts
@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>
<h1 [@zoom]="animationState">Welcome to Angular</h1>
</div>
</div>
</div>
End of Components
24/03/22
Angular Pipes
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.
AsyncPipe
UpperCasePipe
LowerCasePipe
TitleCasePipe
NumberPipe
CurrencyPipe
SlicePipe
PercentPipe
JsonPipe
i18nSelectPipe
i18nPluralPipe
DatePipe
- Angular also allows to create Custom Pipes
Syntax:
data | pipeName:parameter1:parameter2
Pipe Architecture
=============
transform(value:any, ...args[]) {
value is formatted.
return value;
@Pipe({
name: 'pipename'
})
transform(){ }
"pipes"
@Pipe({
name: 'sentencecase'
})
transform(value:any) {
return sentence;
declarations: [
SentenceCasePipe
5. pipedemo.component.ts
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
@Pipe({
name: 'sorting'
})
transform(list:any, reverse?:boolean) {
list.sort();
if(reverse==true){
list.sort();
list.reverse();
return list;
}}
3. pipedemo.component.ts
4. pipedemo.component.html
<div class="container-fluid">
<h2>Cities</h2>
<ol>
{{item}}
</li>
</ol>
</div>
</li>
=================
- uppercase
- lowercase
- titlecase
- slice
25/03/22
Pipes
Custom Pipes
Built-in Pipes
Syntax:
{{ string | uppercase }}
Syntax:
{{ string | slice:startIndex:endIndex }}
{{item}}
</li>
{{item.key}} - {{item.value}}
</li>
Syntax:
{{ value | number }}
{{ value | number:minInteger.maxFraction }}
{{ value | number:minInteger.minFraction-maxFraction}}
Ex:
price = 67000.40;
{{ price | number:'5.2-2' }}
symbol.
Syntax:
Ex:
product:any = {
Price: 67000.400,
Sales: 0.567
format:
short
long
full
shortDate
shortTime
longDate
longTime
fullDate
fullTime
custom:
yy - 2 digits year
Ex:
product = {
10. json : It converts the data into JSON format. It is mostly used
{{ product | json }}
11. i18nSelect : It is used to select suitable value and render
"i18nSelect"
Ex:
pipedemo.component.ts
@Component({
selector: 'app-pipedemo',
templateUrl: './pipedemo.component.html',
styleUrls: ['./pipedemo.component.css']
})
constructor() { }
ngOnInit(): void {
shoppingCart:any[] = [
];
status:any = {
}}
pipedemo.component.html
<div class="container-fluid">
<h2>Shopping Cart</h2>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>City</th>
<th>Delivery Status</th>
</tr>
</thead>
<tbody>
<td>{{item.Name}}</td>
<td>{{item.Price}}</td>
<td>{{item.City}}</td>
<td>{{item.City|i18nSelect:status}}</td>
</tr>
</tbody>
</table>
</div>
26/03/22
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:
1. Add a new file into “app” folder
“captcha.service.ts”
@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;
}
}
2. Register service in “app.module.ts”
providers: [ CaptchaService ],
.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
1. Generate a service
ng g service data --skipTests
2. data.service.ts
@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'}
];
}
}
3. Goto “app.module.ts” and register service
4. Productslist.component.ts
@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();
}
Angular Forms
28/03/22
HttpClient Service
==============
Ans :
Fetch:
HttpClient:
a) Observable
b) Subscriber
Syntax:
GetProducts:Observable<T>() {
GetProduct.subscribe(data=> { })
Ex:
1. Go to "app.module.ts"
import { HttpClientModule } from '@angular/common/http';
imports: [
HttpClientModule
"Fakestoreapi.service.ts"
@Injectable({
providedIn: 'root'
})
GetCategories():Observable<string[]>{
return this.http.get<string[]>('http://fakestoreapi.com/products/categories');
GetProducts():Observable<any[]>{
return this.http.get<any[]>('http://fakestoreapi.com/products');
> ng g c fakestore
4. fakestore.component.ts
@Component({
selector: 'app-fakestore',
templateUrl: './fakestore.component.html',
styleUrls: ['./fakestore.component.css']
})
categories:string[] = [];
products:any[] = [];
ngOnInit(): void {
}}
5. fakestore.component.html
<div class="container-fluid">
<div class="row">
<div class="col-3">
<div>
<div>
<select class="form-select">
{{item | titlecase}}
</option>
</select>
</div>
</div>
</div>
<div class="col-9">
<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.
UserName.pristine
UserName.dirty
UserName.touched
UserName.untouched
UserName.valid
UserName.invalid
UserName.errors
- Heavy on UI
- Separation concerns
- Hard to extend
- Hard to test.
==========================
29/03/22
Syntax:
<form #frmRegister="ngForm">
</form>
Syntax:
frmRegister.value
"UserName:" ",
frmRegister.value.UserName
frmRegister.value.Mobile
(submit) event
(ngSubmit) event
Ex:
templateform.component.ts
@Component({
selector: 'app-templateform',
templateUrl: './templateform.component.html',
styleUrls: ['./templateform.component.css']
})
constructor() { }
ngOnInit(): void {
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}}
templateform.component.html
<div class="container-fluid">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dt>Mobile</dt>
</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>
--------------------------------------------
------------------------------------------
- It will not report the problem of any specific element, it uses entire
--------------------------------------------------------------------------------------------
untouched.
is submitted.
Syntax:
frmRegister.pristine
frmRegister.dirty
Note: All validation services are boolean type, they return true or false.
- required
- minlength
- maxlength
- min
- max
- pattern
Ex:
templateform.component.css
.invalid-style {
padding: 10px;
.valid-style {
padding: 10px;
templateform.component.ts
@Component({
selector: 'app-templateform',
templateUrl: './templateform.component.html',
styleUrls: ['./templateform.component.css']
})
ngOnInit(): void {
FormSubmit(obj:any){
alert(JSON.stringify(obj));
}}
template.component.html
<div class="container-fluid">
<div class="col-5">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
<dt>Mobile</dt>
</dl>
<button *ngIf="frmRegister.dirty">Save</button>
</form>
</div>
<div class="col-7">
<h2>Validation Services</h2>
<dl>
<dd>{{frmRegister.pristine}}</dd>
<dd>{{frmRegister.dirty}}</dd>
<dd>{{frmRegister.invalid}}</dd>
<dt>Submitted</dt>
<dd>{{frmRegister.submitted}}</dd>
</dl>
</div>
</div>
</div>
-----------------------------------------
---------------------------------------------------------------------------------------------
html errors.
Syntax:
UserName.pristine
UserName.dirty
Mobile.invalid
- Angular 13 validation object provides the access for properties using a property reference.
objectName['Property']
templateform.component.html
<div class="container-fluid">
<div class="col-5">
<form #frmRegister="ngForm">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
</dd>
<dt>Mobile</dt>
</dd>
</dl>
<button type="submit">Register</button>
</form>
</div>
<div class="col-7">
</div>
</div>
</div>
30/03/22
NEW MATERIAL
Template Forms
=============
Template Validation
a) Form State
pristine
dirty
valid
invalid
submitted
b) Input State
pristine
dirty
valid
invalid
touched
untouched
Custom Validations:
---------------------------
- You can write your own validation function and bind to any HTML element.
Ex:
templateform.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-templateform',
templateUrl: './templateform.component.html',
styleUrls: ['./templateform.component.css']
})
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="col-5">
<form #frmRegister="ngForm">
<h2>Register User</h2>
<dl>
<dt>User Name</dt>
</dd>
<dt>Mobile</dt>
</dd>
<dt>Your City</dt>
<dd>
<option value="Delhi">Delhi</option>
<option value="Hyd">Hyd</option>
</select>
</dd>
</dd>
<dd>
</dd>
</dd>
</dl>
<button type="submit">Register</button>
</form>
</div>
<div class="col-7">
</div>
</div>
</div>
-------------------------------------------
- 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 {
input.ng-invalid {
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
==============================
- Easy to extend
- Loosely couple
- East to Test
- If you are designing inline component model driven forms will be hard to maintain.
- It is a member of "@angular/forms"
FormControl:
- It is the base class for all form elements like button, textbox, checkbox, radio, listbox etc..
Syntax:
Name.value
Name.pristine
Name.dirty etc..
Template Form:
Model Form:
------------------------------------
<body> Valid
<form>
</form>
<form>
</form>
</body>
<body> Invalid
<form>
<form>
</form>
</form>
</body>
<form>
<div [form]>
</div>
</form>
01/04/22
- Module
ReactiveFormsModule
- Classes
FormGroup
FormControl
FormBuilder
Validators
Syntax:
// controls
});
Syntax:
reference
Syntax:
frmRegister.pristine
frmRegister.dirty
frmRegister.valid
frmRegister.invalid
frmRegister.submitted
Syntax:
Syntax:
<select forControlName="Name">
Note: Angular 13+ versions will not allow to define a control outside form group. Every form element must be
inside form group.
Ex:
imports : [
ReactiveFormsModule
]
Control : formControlName
Syntax:
<form [formGroup]="ParentForm">
<div formGroupName="ChildForm">
</div>
</form>
Ex:
modelform.component.ts
@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
}) })
constructor() { }
ngOnInit(): void {
FormSubmit(obj:any){
alert(JSON.stringify(obj));
UpdatePartial(){
this.frmRegister.patchValue({
frmStock: {
City: 'Hyd'
} }) }}
modelform.component.html
<div class="container-fluid">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dt>Price</dt>
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
</form>
</div>
Note: Allocating memory for control every time will overload memory.
You can design a form with continous memory without disconnected access by using a service
"FormBuilder".
FormBuilder
==========
- FormBuilder is a service.
- Memory is allocated for the first request and the same memory will be used across all requests.
Syntax:
frmRegister:any;
ngOnInit() {
this.frmRegister = this.fb.group({
Name: this.fb.control(''),
frmStock: this.fb.group({
Status: this.fb.control(true)
})
})
Ex:
modelform.component.ts
@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
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({
frmStock: {
City: 'Hyd'
})
modelform.component.html
<div class="container-fluid">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dd><input formControlName="Name" type="text"></dd>
<dt>Price</dt>
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
</form>
</div>
------------------------------
- It is a collection of controls.
Ex:
modelform.component.ts
@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
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(){
}
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({
frmStock: {
City: 'Hyd'
})
modelform.component.html
<div class="container-fluid">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
<dt>Price</dt>
</dd>
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
</form>
</div>
04/04/22
Reactive Forms
- FormGroup
- FormControl
- FormBuilder
control()
group()
array()
======================
Syntax:
- Validators class will provide the properties for validating input elements.
Syntax:
control('value', [Validators.required]);
- Validation properties are defined in controller, however the validation messages are configured in UI.
Syntax:
this.frmRegister = fb.group({
})
get Name() {
</div>
Note: Every element in form requires an Accessor, if you are using a Form Builder. [getter]
2. Model Driven
ngModel
ngForm
5. Reactive Forms
- FormGroup
- FormControl
- FormBuilder
a) group()
b) control()
c) array()
- Validators
Ex:
modelform.component.ts
@Component({
selector: 'app-modelform',
templateUrl: './modelform.component.html',
styleUrls: ['./modelform.component.css']
})
frmRegister:any;
ngOnInit(): void {
this.frmRegister = this.fb.group({
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() {
get NewControls(){
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({
frmStock: {
City: 'Hyd'
})
modelform.component.html
<div class="container-fluid">
<h2>Basic Details</h2>
<dl>
<dt>Name</dt>
</dd>
<dt>Price</dt>
</dd>
<h3>Stock Details</h3>
<dl>
<dt>Status</dt>
<dt>City</dt>
<dd>
<select formControlName="City">
<option>Delhi</option>
<option>Hyd</option>
<option>Chennai</option>
</select>
</dd>
</dl>
</div>
</dl>
<button>Register</button>
</form>
</div>
Angular Routing
----------------------
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.
http://www.amazon.in/electronics.jsp?category=mobiles&brand=samsung&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 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.
a) Client Side
b) Server Side
Server Side:
fakestoreapi.com/products?id=2
fakestoreapi.com/products/2
Route Architecture
05/04/22
Angular Routing
----------------------
- RouterModule
- Routes
- "RouterModule" provides set of properties and methods to export and import routes for application.
---------------------------------------
(or)
Ex:
"app-routing.module.ts"
@NgModule({
imports : [RouterModule.forRoot(routes)],
exports : [RouterModule]
})
export class AppRoutingModule { }
imports: [
BrowserModule,
AppRoutingModule,
RouterModule
],
-------------------------------------
a) path
b) component
- Design Navigation in
"app.component.html"
a) <router-outlet>
b) routerLink
Ex:
1. Add Components
> ng g c home
> ng g c categories
> ng g c notfound
2. home.component.html
3. categories.component.ts
@Component({
selector: 'app-categories',
templateUrl: './categories.component.html',
styleUrls: ['./categories.component.css']
})
categories:any[] = [];
constructor() { }
ngOnInit(): void {
fetch('http://fakestoreapi.com/products/categories')
.then(response=>response.json())
.then(data=> {
this.categories = data;
})
}
4. categories.component.html
<h2>Categories</h2>
<ol>
{{item|titlecase}}
</li>
</ol>
5. notfound.component.ts
@Component({
selector: 'app-notfound',
templateUrl: './notfound.component.html',
styleUrls: ['./notfound.component.css']
})
location:any;
constructor() { }
ngOnInit(): void {
this.location = location.pathname;
}}
6. notfound.component.html
<h2>Not Found</h2>
7. Go to "app.component.html"
<div class="container-fluid">
</header>
<section>
<div class="row">
<div class="col-3">
<ul class="list-unstyled">
</ul>
</div>
<div class="col-9">
<router-outlet></router-outlet>
</div>
</div>
</section>
</div>
8. Go to "app-routing.module.ts"
];
@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.
{ path: 'home/:param1/:param2/:param3..' }
- To access and use the route parameter you need "ActivatedRoute" service.
.get()
06/04/22
Route Parameter
------------------------
Syntax:
Syntax:
http://localhost:4200/details/1/Mobile
- You can access and use route parameters in any component by using "ActivatedRoute" service.
Syntax:
ProductId:any;
Name:any;
ngOnInit() {
this.ProductId = this.route.snapshot.paramMap.get("id");
----------------------------------
- A route path can have another component to display within the context by using "children".
Syntax:
children: [
<parentcomponent>
details
<router-outlet> </router-outlet>
</parentcomponent>
07/04/22
- MongoDB Database
- Express Middleware
Database
-------------
https://www.mongodb.com/try/download/community
OS : windows
Package : MSI
- open "services.msc"
- select start
5. MongoDB Terminology
RDBMS MongoDB
Database Database
Table Collection
Records Document
Field Field
{ "UserId": "john_nit",
"UserName": "John",
"Password": "john@12",
"Age": 22,
"Email": "[email protected]",
"Mobile": "+919876543210" }
Summary:
"www.connectionstrings.com"
----------------------
We will use
"index.js"
app.use(cors());
app.use(express.urlencoded({
extended: true
}));
app.use(express.json());
app.get("/getusers", function(request, response){
if(!err){
dbo.collection("tblusers").find().toArray(function(err, documents){
if(!err){
response.send(documents);
})
})
});
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
};
if(!err){
if(!err) {
console.log("Record Inserted");
})
})
})
app.listen(8080);
09/04/22
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"
- Route Cycle hook methods are implemented from interfaces, which means every route guard can handle all
hook methods.
Lazy Routes
Deployment
Testing
12-04-22
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.
"loadChildren"
Syntax:
Note: Angular can implement lazy loading for routes when you configure application with various modules.
Ans: Yes
Ex:
3. Go to app.component.html
<div>
<span>|</span>
<a routerLink="nri">NRI</a>
<span>|</span>
<a routerLink="agri">AGRI-Govt.India</a>
</div>
</div>
];
----------------------------
- It is the process of testing every component, service or pipe and ensure that they are matching the requirements.
"Jasmine - Karma"
- It comprises of 3 phases
a) Arrange
b) Act
c) Assert
Test Methods
describe()
expect()
toBe(),
toBeTruthy()
toBeEqual()
> 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']
})
constructor() { }
ngOnInit(): void {
CalculateTotal(qty:number, price:number){
Title(str:string) {
return str;
home.component.spec.ts
describe('HomeComponentTest', function(){
expect(component.CalculateTotal(2,4000)).toBe(12000);
})
})
})
13/04/22
Deployment
Deployment
a) Syntactical errors
b) Dependencies
c) Directives
d) Meta data
a) Local Servers
IIS
XAMPP
WAMP
MAMP etc..
b) Cloud Servers
Firebase
Azure
GitHub Pages
AWS
Now
Netify etc..
3. Go to Firebase "Console"
Step-1:
"angular-fakeshop"
Step-2:
- Enable Analytics
Step-3
- Select Account
C:\>firebase login
6. Open your angular project and build for production (go live)
This will compile, check for dependencies, convert typescript into javascript and then copy all file into output
directory "dist".
[resources - static]
[startup page]
ng deploy -- hosting
https://angular-fakeshop.web.app
[it will copy all files and folders of 'dist' into cloud]
Domain:
https://angular-fakeshop.firebaseapp.com/home