Soc F
Soc F
C
MEAN Stack Technologies-Module II- Angular JS,
MongoDB (Skill Oriented Course)
EXERCISE-1
a) Angular application setup
To develop an application using Angular on a local system, you need to set up a development environment
that includes the installation of:
• Node.js (^12.20.2 || ^14.15.5 || ^16.10.0) and npm (min version required 6.13.4)
• Angular CLI
• Visual Studio Code
Install Node.js (^12.20.2 || ^14.15.5 || ^16.10.0) from Sparsh Downloads as shown below and take help
from CCD to get it installed.
node -v
Angular CLI can be installed using node package manager as shown below:
Note: Node modules should be downloaded from Node Repository managed by Infosys. By default, Node
Package Manager (NPM) points to global Node registry and downloads the Node modules from there. To
make NPM point to Node Repository managed by Infosys, use below commands.
Post npm login, it will ask for username, password, and email. Enter the username without @infosys.com, enter
your Infosys password and email id.
1
DATE:____/______/2023
C
Test successful installation of Angular CLI using the following command
Note: Sometimes additional dependencies might throw an error during CLI installation but still check
whether CLI is installed or not using the following command. If the version gets displayed, you can ignore
the errors.
1. D:\> ng v
Angular CLI is a command-line interface tool to build Angular applications. It makes application
development faster and easier to maintain.
Using CLI, you can create projects, add files to them, and perform development tasks such as testing,
bundling, and deployment of applications.
Command Purpose
npm install -g @angular/cli Installs Angular CLI globally
ng new <project name> Creates a new Angular application
ng update @angular/cli
@angular/core Updates Angular to latest version
2
DATE:____/______/2023
C
b) Components and Modules
Aim: Create a new component called hello and render Hello Angular on the page
Program:
1. In the same MyApp application created earlier, create a new component called hello using the following
CLI command
D:\MyApp> ng generate component hello
2. This command will create a new folder with the name hello with the following files placed inside it
3. Open hello.component.ts file and create a property called courseName of type string and initialize it to
"Angular" as shown below in Line number 9
5. Open hello.component.css and add the following styles for the paragraph element
p{
color:blue;
font-size:20px;
}
3
DATE:____/______/2023
6. Open app.module.ts file and add HelloComponent to bootstrap property as shown below in Line 11 to
load it for execution
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello/hello.component';
@NgModule({
imports: [BrowserModule,AppRoutingModule],
declarations: [AppComponent, HelloComponent],
providers: [],
bootstrap: [HelloComponent]
})
export class AppModule { }
7. Open index.html and load the hello component by using its selector name i.e., app-hello as shown
below in Line 11
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-hello></app-hello>
</body>
</html>
4
DATE:____/______/2023
C
c) Elements of Template
Add an event to the hello component template and when it is clicked, it should change the courseName.
Introduction to Templates
• Templates separate the view layer from the rest of the framework.
• You can change the view layer without breaking the application.
• Templates in Angular represents a view and its role is to display data and change the data whenever
an event occurs
• The default language for templates is HTML
Creating a template
• Inline Template
• External Template
You can create an inline template in a component class itself using the template property of the @Component
decorator.
app.component.ts
Output:
5
DATE:____/______/2023
C
• By default, Angular CLI uses the external template.
• It binds the external template with a component using templateUrl option.
Example
app.component.html
app.component.ts
11.
Output:
6
DATE:____/______/2023
C
d) Change Detection
Aim: To prove the change detection
Program:
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
greeting = '';
change() {
this.greeting = 'Good Morning';
}
}
app.component.html
<h1>{{ greeting }}</h1>
<button (click)="change()">Greet</button>
Output:
7
DATE:____/______/2023
C
EXERCISE-2
a) STRUCTURAL DIRECTIVES – ngIf
Aim: Create a login form with username and password fields. If the user enters the correct
credentials, it should render a "Welcome <<username>>" message otherwise it should render
"Invalid Login!!! Please try again..." message.
Program:
<div *ngIf="!submitted">
<form>
<label>User Name</label>
<input type="text" #username /><br /><br />
<label for="password">Password</label>
<input type="password" name="password" #password /><br />
</form>
<button (click)="onSubmit(username.value, password.value)">Login</button>
</div>
8
DATE:____/______/2023
C
<div *ngIf="submitted">
<div *ngIf="isAuthenticated; else failureMsg">
<h4>Welcome {{ userName }}</h4>
</div>
<ng-template #failureMsg>
<h4>Invalid Login !!! Please try again...</h4>
</ng-template>
<button type="button" (click)="submitted = false">Back</button>
</div>
Add AppComponent to the bootstrap property in the root module file i.e., app.module.ts
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
9
DATE:____/______/2023
C
Save the files and check the output in the browser.
Output:
10
DATE:____/______/2023
C
B)ngFor
Aim: Create a courses array and rendering it in the template using ngFor directive in a list format.
Program:
<ul>
<li *ngFor="let course of courses; let i = index">
{{ i }} - {{ course.name }}
</li>
</ul>
11
DATE:____/______/2023
C
b) ngSWITCH
Aim: Displaying the correct option based on the value passed to ngSwitch directive
Program:
<h4>
Current choice is {{ choice }}
</h4>
<div [ngSwitch]="choice">
<p *ngSwitchCase="1">First Choice</p>
<p *ngSwitchCase="2">Second Choice</p>
<p *ngSwitchCase="3">Third Choice</p>
<p *ngSwitchCase="2">Second Choice Again</p>
<p *ngSwitchDefault>Default Choice</p>
</div>
<div>
<button (click)="nextChoice()">
Next Choice
</button>
</div>
Output:
12
DATE:____/______/2023
C
c) Custom Structural Directive
Aim: Create a custom structural directive called 'repeat' which should repeat the element given a
number of times
Program:
13
DATE:____/______/2023
C
Write the below-given code in app.component.html
<h3>Structural Directive</h3>
<p *appRepeat="5">I am being repeated...</p>
Output:
14
DATE:____/______/2023
C
EXERCISE-3
Attribute Directives -ngStyle
Aim: Apply multiple CSS classes to the text using ngClass directive.
Program:
Write the below-given code in app.component.ts
import { Component } from '@angular/core'; @Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
colorName = 'red';
fontWeight = 'bold';
borderStyle = '1px solid black'; }
Output:
15
DATE:____/______/2023
C
a) ngClass
Aim: Applying multiple CSS classes to the text using ngClass directive. The output should be
as shown below
Program:
Write the below-given code in app.component.ts
Output:
16
DATE:____/______/2023
C
b) Custom Attribute Directive
Aim: Create an attribute directive called 'showMessage' which should display the given message
in a paragraph when a user clicks on it and should change the text color to red.
Program:
Generate a directive called 'message' using the following command
D:\MyApp>ng generate directive message
Above command will add MessageDirective class to the declarations property in the app.module.ts file
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { MessageDirective } from './message.directive';
@NgModule({
declarations: [
AppComponent,
MessageDirective
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
17
DATE:____/______/2023
C
Write the below-given code in app.component.html
<h3>Attribute Directive</h3>
<p [appMessage]="myMessage">Click Here</p>
Output:
18
DATE:____/______/2023
C
EXERCISE-4
Property Binding
Aim: Binding image with class property using property binding.
Program:
Write the following code in app.component.ts as shown below
Create a folder named "imgs" inside src/assets and place a logo.png file inside it.
Write the following code in app.component.html as shown below
<img [src]='imgUrl'>
Save the files and check the output in the browser
Output:
19
DATE:____/______/2023
a) Attribute Binding
Aim: Binding colspan attribute of a table element to the class property to display the following output
Program:
Write the below-given code in app.component.ts
<table border=1>
<tr>
<td [attr.colspan]="colspanValue"> First </td>
<td>Second</td>
</tr>
<tr>
<td>Third</td>
<td>Fourth</td>
<td>Fifth</td>
</tr>
</table>
20
DATE:____/______/2023
C
b) Style and Event Binding
Aim: Binding a textbox with a property using two-way data binding.
Program:
Write the below-given code in app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
}
Write the below-given code in app.component.html
21
DATE:____/______/2023
C
EXERCISE-5
Built in Pipes
Aim: Display the product code in lowercase and product name in uppercase using built-in pipes.
Program:
Output:
22
DATE:____/______/2023
C
a) Passing Parameters to Pipes
Aim: Apply built-in pipes with parameters to display product details.
Program:
23
DATE:____/______/2023
C
<td> {{ productTax | percent : '.2' }} </td>
</tr>
<tr>
<th> Product Rating </th>
<td>{{ productRating | number:'1.3-5'}} </td>
</tr>
</table>
Output:
24
DATE:____/______/2023
C
b) Nested Components Basics
Aim: Load CourseslistComponent in the root component when a user clicks on the View courses
list button.
Program:
Create a component called coursesList using the following CLI
command D:\MyApp>ng generate component coursesList
CoursesListComponent class will be added in the app.module.ts file
25
DATE:____/______/2023
C
Write the below-given code in courses-list.component.html
<table border="1">
<thead>
<tr>
<th>Course ID</th>
<th>Course Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let course of courses">
<td>{{ course.courseId }}</td>
<td>{{ course.courseName }}</td>
</tr>
</tbody>
</table>
tr{
text-align:center;
}
<h2>Popular Courses</h2>
<button (click)="show = true">View Courses list</button><br /><br />
<div *ngIf="show">
<app-courses-list></app-courses-list>
</div>
26
DATE:____/______/2023
C
Save the files and check the output in the browser
Output:
27
DATE:____/______/2023
C
EXERCISE-6
28
DATE:____/______/2023
C
</tr>
</thead>
<tbody>
<tr *ngFor="let c of course">
<td>{{ c.courseId }}</td>
<td>{{ c.courseName }}</td>
</tr>
</tbody>
</table>
<h2>Course Details</h2>
Select a course to view
<select #course (change)="name = course.value">
<option value="Node JS">Node JS</option>
<option value="Typescript">Typescript</option>
<option value="Angular">Angular</option>
<option value="React JS">React JS</option></select><br /><br />
<app-courses-list [cName]="name"></app-courses-list>
Output:
29
DATE:____/______/2023
C
b) Passing data from Child Component to Container Component
Aim: Create an AppComponent that loads another component called theCoursesList component.
Create another component calledCoursesListComponent which should display the courses list in a
table along with a register .button in each row. When a user clicks on the register button, it
should send that courseName value back to AppComponent where it should display the
registration successful message along with courseName
Program:
Open the courses-list.component.ts file created in the previous example and add the following code
<table border="1">
<thead>
<tr>
<th>Course ID</th>
<th>Course Name</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let course of courses">
<td>{{ course.courseId }}</td>
<td>{{ course.courseName }}</td>
<td><button (click)="register(course.courseName)">Register</button></td>
</tr>
</tbody>
30
DATE:____/______/2023
C
</table>
Add the following in app.component.html
<h2>Courses List</h2>
<app-courses-list (registerEvent)="courseReg($event)"></app-courses-list>
<br /><br />
<div *ngIf="message">{{ message }}</div>
Output:
31
DATE:____/______/2023
C
c) Shadow DOM
Aim: Apply ShadowDOM and None encapsulation modes to components.
Program:
ViewEncapsulation.Emulated
Create a component called First using the following CLI
command D:\MyApp>ng generate component first
Write the below-given code in first.component.css
.cmp {
padding: 6px;
margin: 6px;
border: blue 2px solid;
}
Write the below-given code in first.component.html
<div class="cmp">First Component</div>
Create a component called Second using the following CLI command
D:\MyApp>ng generate component second
Write the below-given code in second.component.css
.cmp {
border: green 2px solid;
padding: 6px;
margin: 6px;
}
Write the below-given code in second.component.html
<div class="cmp">Second Component</div>
Write the below-given code in second.component.ts
32
DATE:____/______/2023
C
.cmp {
padding: 8px;
margin: 6px;
border: 2px solid red;
}
Output:
ViewEncapsulation.ShadowDOM
Set ViewEncapsulation to none mode in app.component.ts file
33
DATE:____/______/2023
C
Set ViewEncapsulation to none mode in second.component.ts file
Output:
34
DATE:____/______/2023
35
DATE:____/______/2023
C
ngOnDestroy(): void {
console.log('Destroy');
}
}
36
DATE:____/______/2023
C
EXERCISE-7
a) Template Driven Forms
Aim: Creating a course registration form as a template-driven form.
Program:
Write the below-given code in app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from
'@angular/platform-browser'; import { FormsModule } from
'@angular/forms'; import { AppRoutingModule } from './app-
routing.module'; import { AppComponent } from './app.component';
@NgModule({ declarations: [
AppComponent
],
imports: [ BrowserModule,
AppRoutingModule,
FormsModule
], providers: [], bootstrap:
[AppComponent]
}) export class AppModule { }
37
DATE:____/______/2023
38
DATE:____/______/2023
C
Output:
39
DATE:____/______/2023
C
b) Model Driven forms or Reactive forms
Aim: Create an employee registration form as a reactive form.
Program:
Write the below-given code in app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import {
NgModule } from '@angular/core'; import { ReactiveFormsModule } from
'@angular/forms'; import { AppComponent } from './app.component';
import { RegistrationFormComponent } from
'./registrationform/registrationform.component'; @NgModule({
declarations: [ AppComponent,
RegistrationFormComponent ],
imports: [
BrowserModule,
ReactiveFormsModule
], providers: [], bootstrap:
[AppComponent]
}) export class AppModule { }
40
DATE:____/______/2023
C
street: [],
zip: [],
city: []
})
});
}
}
Write the below-given code in registration-form.component.html
<div class="container">
<h1>Registration Form</h1>
<form [formGroup]="registerForm">
<div class="form-group">
<label>First Name</label>
<input type="text" class="form-control" formControlName="firstName">
<div *ngIf="registerForm.controls['firstName'].errors" class="alert alert-danger">
Firstname field is invalid.
<p *ngIf="registerForm.controls['firstName'].errors?.['required']">
This field is required!
</p>
</div>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" class="form-control" formControlName="lastName">
<div *ngIf="registerForm.controls['lastName'].errors" class="alert alert-danger">
Lastname field is invalid.
<p *ngIf="registerForm.controls['lastName'].errors?.['required']">
This field is required!
</p>
</div>
</div>
<div class="form-group">
<fieldset formGroupName="address">
<legend>Address:</legend>
<label>Street</label>
<input type="text" class="form-control" formControlName="street">
<label>Zip</label>
<input type="text" class="form-control" formControlName="zip">
<label>City</label>
<input type="text" class="form-control" formControlName="city">
</fieldset>
</div>
<button type="submit" class="btn btn-primary" (click)="submitted=true">Submit</button>
</form>
41
DATE:____/______/2023
C
<br/>
<div [hidden]="!submitted">
<h3> Employee Details </h3>
<p>First Name: {{ registerForm.get('firstName')?.value }} </p>
<p> Last Name: {{ registerForm.get('lastName')?.value }} </p>
<p> Street: {{ registerForm.get('address.street')?.value }}</p>
<p> Zip: {{ registerForm.get('address.zip')?.value }} </p>
<p> City: {{ registerForm.get('address.city')?.value }}</p>
</div>
</div>
Write the below-given code in registration-form.component.css
.ng-valid[required] {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
Write the below-given code in app.component.html
<app-registration-form></app-registration-form>
Save the files and check the output in the browser
Output:
42
DATE:____/______/2023
C
c) Custom Validators in Reactive Forms
Aim: Creating a custom validator for an email field in the employee registration form (reactive
form)
Program:
Write a separate function in registration-form.component.ts for custom validation as shown below.
43
DATE:____/______/2023
C
<div class="container">
<h1>Registration Form</h1>
<form [formGroup]="registerForm">
<div class="form-group">
<label>First Name</label>
<input type="text" class="form-control" formControlName="firstName" />
<div *ngIf="registerForm.controls.firstName.errors" class="alert alert-danger">
Firstname field is invalid.
<p *ngIf="registerForm.controls.firstName.errors?.required">
This field is required!
</p>
</div>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" class="form-control" formControlName="lastName" />
<div *ngIf="registerForm.controls.lastName.errors" class="alert alert-danger">
Lastname field is invaliddd.
<p *ngIf="registerForm.controls.lastName.errors?.required">
This field is required!
</p>
</div>
</div>
<div class="form-group">
<fieldset formGroupName="address">
<label>Street</label>
<input type="text" class="form-control" formControlName="street" />
<label>Zip</label>
<input type="text" class="form-control" formControlName="zip" />
<label>City</label>
<input type="text" class="form-control" formControlName="city" />
</fieldset>
</div>
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" formControlName="email" />
<div *ngIf="registerForm.controls.email.errors" class="alert alert-danger">
Email field is invalid.
<p *ngIf="registerForm.controls.email.errors?.required">
This field is required!
</p>
<p *ngIf="registerForm.controls.email.errors?.emailInvalid">
44
DATE:____/______/2023
C
{{ registerForm.controls.email.errors?.emailInvalid.message }}
</p>
</div>
</div>
<button type="submit" class="btn btn-primary" (click)="submitted = true">
Submit
</button>
</form>
<br/>
<div [hidden]="!submitted">
<h3>Employee Details</h3>
<p>First Name: {{ registerForm.controls.firstName.value }}</p>
<p>Last Name: {{ registerForm.controls.lastName.value }}</p>
<p>Street: {{ registerForm.controls.address.value.street }}</p>
<p>Zip: {{ registerForm.controls.address.value.zip }}</p>
<p>City: {{ registerForm.controls.address.value.city }}</p>
<p>Email: {{ registerForm.controls.email.value }}</p>
</div>
</div>
Output:
45
DATE:____/______/2023
C
EXERCISE-8
Aim: Create a custom validator for the email field in the course registration form
Program:
app.component.ts
<label for="phone">Phone:</label>
<input type="tel" id="phone" name="phone" [(ngModel)]="phone" required pattern="[0-9]{10}">
46
DATE:____/______/2023
C
<select id="course" name="course" [(ngModel)]="selectedCourse" required>
<option value="Angular">Angular</option>
<option value="HTML">HTML</option>
<option value="Machine learning">Machine learning</option>
</select>
course-registration-form.component.ts
Output:
47
DATE:____/______/2023
b) Services Basics
Aim: Create a Book Component which fetches book details like id, name and displays them on
the page in a list format. Store the book details in an array and fetch the data using a custom
service.
Program:
Create BookComponent by using the following CLI
command. D:\MyApp>ng generate component book
Create a file with the name book.ts under the book folder and add the following code.
Create a file with the name books-data.ts under the book folder and add the following code.
48
DATE:____/______/2023
C
return BOOKS;
}
}
Add the following code in the book.component.ts file
<h2>My Books</h2>
<ul class="books">
<li *ngFor="let book of books">
<span class="badge">{{book.id}}</span> {{book.name}}
</li>
</ul>
Add the following code in book.component.css which has styles for books
.books {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 13em;
}
.books li {
cursor: pointer;
position: relative;
left: 0;
background-color: #eee;
margin: 0.5em;
49
DATE:____/______/2023
C
padding: 0.3em 0;
height: 1.5em;
border-radius: 4px;
}
.books li:hover {
color: #607d8b;
background-color: #ddd;
left: 0.1em;
}
.books .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607d8b;
line-height: 0.5em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: 0.8em;
border-radius: 4px 0 0 4px;
}
Add the following code in app.component.html
<app-book></app-book>
Save the files and check the output in the browser
Output:
50
DATE:____/______/2023
C
c) RxJS Observables
Aim: Create and use an observable in Angular.
Program:
app.component.ts
Output:
51
DATE:____/______/2023
C
EXERCISE-9
a) Server Communication using HttpClient
Aim: Create an application for Server Communication using HttpClient
Program:
Create a new service called api using the Angular CLI:
ng generate api
api.component.ts
52
DATE:____/______/2023
Output:
53
DATE:____/______/2023
[
{
"productId": 1,
"productName": "Samsung Galaxy Note 7",
"productCode": "MOB-120",
"description": "64GB, Coral Blue",
"price": 800,
"imageUrl": "assets/imgs/samsung_note7_coralblue.jpg",
"manufacturer": "Samsung",
"ostype": "Android",
"rating": 4
},
{
"productId": 2,
"productName": "Samsung Galaxy Note 7",
"productCode": "MOB-124",
"description": "64GB, Gold",
"price": 850,
"imageUrl": "assets/imgs/samsung_note7_gold.jpg",
"manufacturer": "Samsung",
"ostype": "Android",
"rating": 4
}, ...
]
tablets.json
[
{
"productId": 1,
"productName": "Apple iPad Mini 2",
"productCode": "TAB-120",
54
DATE:____/______/2023
C
"description": "16GB, White",
"price": 450,
"imageUrl": "assets/imgs/apple_ipad_mini.jpg",
"manufacturer": "Apple",
"ostype": "iOS",
"rating": 4
},
{
"productId": 2,
"productName": "Apple iPad Air2",
"productCode": "TAB-124",
"description": "64GB, Black",
"price": 600,
"imageUrl": "assets/imgs/ipad_air.jpg",
"manufacturer": "Apple",
"ostype": "iOS",
"rating": 3
},
...
]
Explore the methods present in the product.service.ts file from the products folder. Observe the code
given below:
55
DATE:____/______/2023
C
catchError(this.handleError));
} else if (this.producttype === 'mobile') {
return this.http.get<Product[]>('./assets/products/mobiles.json').pipe(
tap((products) => this.products = products),
catchError(this.handleError));
}
else
throw new Error();
}
// Fetches the selected product details
getProduct(id: number): Observable<Product> {
return this.getProducts().pipe(
map(products => products.filter(product => product.productId === id)[0]));
}
// Error Handling code
private handleError(err: HttpErrorResponse) {
return throwError(() => err.error() || 'Server error');
}
}
56
DATE:____/______/2023
C
Now open the product-list.component.ts file to explore injecting a product service class
import { AfterViewInit, Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
import { ProductService } from '../product.service';
import { Cart } from '../cart/Cart';
import { Product } from '../product';
import { LoginService } from 'src/app/login/login.service';
@Component({
templateUrl: 'product-list.component.html',
styleUrls: ['product-list.component.css']
})
export class ProductListComponent implements OnInit, AfterViewInit
{ chkman: any = [];
chkmanos: any =
[];rate: number = 0;
pageTitle = 'mCart';
imageWidth = 80;
imageHeight = 120;
imageMargin = 12;
showImage =
false; listFilter:
string = '';
57
DATE:____/______/2023
C
checkedPrice: any[] =
[];sub: any;
i = 0;
sortoption = '';
chkmanosprice: any = [];
@ViewChild('loginEl')
loginVal!: ElementRef;
@ViewChild('welcomeEl'
) welcomeVal!:
ElementRef;
// Fetches the products data from service class
constructor(private productService: ProductService, private loginService: LoginService, private renderer:
Renderer2) {
}
ngAfterViewInit() {
this.loginVal = this.loginService.loginElement;
this.welcomeVal =
this.loginService.welcomeElement;
this.renderer.setProperty(this.loginVal.nativeElement, 'innerText', 'Logout');
this.renderer.setStyle(this.welcomeVal.nativeElement, 'display', 'inline');
let welcomeText="Welcome "+this.loginService.username+ " ";
this.renderer.setProperty(this.welcomeVal.nativeElement, 'innerText', welcomeText);
this.renderer.setStyle(this.welcomeVal.nativeElement, 'color', '#ff0080');
}
ngOnInit() {
this.orderId++;
this.productService.getProducts()
.subscribe({
next:products =>
{
this.productService.products = products;
this.products = this.productService.products;
this.chkmanosprice =this.products
},
error:error => this.errorMessage = error});
if (this.productService.selectedProducts.length > 0) {
this.selectedItems = Number(sessionStorage.getItem('selectedItems')); this.total
= Number(sessionStorage.getItem('grandTotal'));
}
}
checkManufacturers(cManuf: any[], cProducts: any[], chkman: any[])
{ if (cManuf.length > 0) {
for (let checkManuf of cManuf) {
for (let checkProd of cProducts)
{
if (checkProd.manufacturer.toLowerCase() === checkManuf.toLowerCase()) {
this.chkman.push(checkProd);
}
}
58
DATE:____/______/2023
C
}
} else {
this.chkman = cProducts;
}
}
checkOpsystem(cOS: any[], chkman: any[], chkmanos: any[])
{ if (cOS.length > 0) {
for (let checkOS of cOS) {
for (let chkmann of chkman) {
if (chkmann.ostype.toLowerCase() === checkOS.toLowerCase()) {
this.chkmanos.push(chkmann);
}
}
}
} else {
this.chkmanos = chkman;
}
}
checkPrices(checkedPrice: any[], chkmanosprice: any[], chkmanos: any[])
{ if (checkedPrice.length > 0) {
for (let checkPrice of checkedPrice)
{ for (let chkmanfos of chkmanos)
{
if (checkPrice === '300-450') {
if (chkmanfos.price >= 300 && chkmanfos.price <= 450)
{ this.chkmanosprice.push(chkmanfos);
}
}
if (checkPrice === '450-600') {
if (chkmanfos.price > 450 && chkmanfos.price <= 600)
{ this.chkmanosprice.push(chkmanfos);
}
}
if (checkPrice === '600-800') {
if (chkmanfos.price > 600 && chkmanfos.price <= 800)
{ this.chkmanosprice.push(chkmanfos);
}
}
if (checkPrice === '800-1000') {
if (chkmanfos.price > 800 && chkmanfos.price <= 1000) {
this.chkmanosprice.push(chkmanfos);
}
}
}
}
} else {
59
DATE:____/______/2023
C
this.chkmanosprice = chkmanos;
}
}
// filtering functionality
filter(name: any) {
let checkedProducts: any[];
this.chkman = [];
this.chkmanos = [];
this.chkmanosprice = [];
const index = 0;
checkedProducts = this.productService.products;
60
DATE:____/______/2023
C
this.cart.orderId = 'ORD_' + this.orderId;
this.cart.productId = id;
this.cart.userId = sessionStorage.getItem('username') + '';
this.cart.productName = product.productName;
this.cart.price = product.price;
this.cart.quantity = 1;
this.cart.dateOfPurchase = new Date().toString();
this.cart.totalPrice = product.price * this.cart.quantity;
this.productService.selectedProducts.push(this.cart);
sessionStorage.setItem('selectedProducts', JSON.stringify(this.productService.selectedProducts));
this.orderId++;
}
}
// Search box functionality
// Searches based on manufacturer name
searchtext() {
this.products = this.productService.products;
if (this.listFilter.length > 0) {
this.products = this.products.filter((product: Product) =>
product.manufacturer.toLowerCase().indexOf(this.listFilter) !== -1);
}
}
// Invoked when a tab (Tablets/Mobiles) is clicked
// Displays tablets or mobiles data accordingly
tabselect(producttype: string) {
this.manufacturers = [{ 'id': 'Samsung', 'checked': false },
{ 'id': 'Microsoft', 'checked': false },
{ 'id': 'Apple', 'checked': false },
{ 'id': 'Micromax', 'checked': false }
];
this.os = [{ 'id': 'Android', 'checked': false },
{ 'id': 'Windows', 'checked': false },
{ 'id': 'iOS', 'checked': false }];
this.price_range = [{ 'id': '300-450', 'checked': false },
{ 'id': '450-600', 'checked': false },
{ 'id': '600-800', 'checked': false },
{ 'id': '800-1000', 'checked': false }];
this.products = [];
this.productService.producttype = producttype;
this.productService.getProducts().subscribe({
next: products => {
this.products = products;
this.sortoption='';
},
error: error => this.errorMessage = error
61
DATE:____/______/2023
C
});
}
// Invoked when user select an option in sort drop down
// changes the sortoption value accordingly
onChange(value: string) {
this.sortoption = value;
}
}
Output:
• Observe below the output of ProductListComponent,
• Here, the products list is displayed by making HTTP call to the JSON file
• The JSON files are stored under the assets folder.
62
DATE:____/______/2023
C
EXERCISE-10
a) Routing Basics, Router Links
Aim: Create multiple components and add routing to provide navigation between them.
Program:
<h3>Top Books</h3>
<div class="grid grid-pad">
<div *ngFor="let book of books" (click)="gotoDetail(book)" class="col-1-4">
<div class="module book">
<h4>{{ book.name }}</h4>
</div>
</div>
63
DATE:____/______/2023
C
</div>
<h3>Top Books</h3>
<div class="grid grid-pad">
<div *ngFor="let book of books" (click)="gotoDetail(book)" class="col-1-4">
<div class="module book">
<h4>{{ book.name }}</h4>
</div>
</div>
</div>
5. Open dashboard.component.css and add the following code
[class*="col-"] {
float: left;
}
*,
*:after,
*:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center;
margin-bottom: 0;
}
[class*="col-"] {
padding-right: 20px;
padding-bottom: 20px;
}
[class*="col-"]:last-of-type {
padding-right: 0;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.module {
padding: 20px;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607d8b;
border-radius: 2px;
64
DATE:____/______/2023
C
}
h4 {
position: relative;
}
.module:hover {
background-color: #eee;
cursor: pointer;
color: #607d8b;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*="col-"]:last-of-type {
padding-right: 20px;
}
@media (max-width: 600px) {
.module {
font-size: 10px;
max-height: 75px;
}
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
.module {
min-width: 60px;
}
}
65
DATE:____/______/2023
C
booksUrl = 'http://localhost:3020/bookList';
private txtUrl = './assets/sample.txt';
constructor(private http: HttpClient) { }
getBooks(): Observable<Book[]> {
return this.http.get<any>(this.booksUrl, {observe:'response'}).pipe(
tap((data: any) => console.log('Data Fetched:' + JSON.stringify(data))),
catchError(this.handleError));
}
getBook(id: any) {
return this.getBooks().pipe(
map((books) => books.find((book) => book.id == id))
);
}
addBook(book: Book): Observable<any> {
const options = new HttpHeaders({ 'Content-Type': 'application/json' });
return this.http.post('http://localhost:3020/addBook', book, { headers: options }).pipe(
catchError(this.handleError));
}
updateBook(book: Book): Observable<any> {
const options = new HttpHeaders({ 'Content-Type': 'application/json' });
return this.http.put<any>('http://localhost:3020/update', book, { headers: options }).pipe(tap((_:
any) => console.log(`updated hero id=${book.id}`)),
catchError(this.handleError)
);
}
deleteBook(bookId: number): Observable<any>
{ const url = `${this.booksUrl}/${bookId}`;
return this.http.delete(url).pipe(
catchError(this.handleError));
}
private handleError(err: HttpErrorResponse): Observable<any> {
let errMsg = '';
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('An error occurred:', err.error.message);
errMsg = err.error.message;
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.log(`Backend returned code ${err.status}`);
errMsg = err.error.status;
}
return throwError(()=>errMsg);
}
}
66
DATE:____/______/2023
C
8. Open book-detail.component.ts and add the following code
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Book } from '../book/book';
import { BookService } from '../book/book.service';
@Component({
selector: 'app-book-detail',
templateUrl: './book-detail.component.html',
styleUrls: ['./book-detail.component.css'],
})
export class BookDetailComponent implements OnInit {
book!: Book;
error!: any;
constructor(
private bookService: BookService,
private route: ActivatedRoute
){}
ngOnInit() {
this.route.paramsMap.subscribe(params => {
this.bookService.getBook(params.get('id')).subscribe((book) => {
this.book = book ?? this.book;
});
});
}
goBack() {
window.history.back();
}
}
9. Open book-detail.component.html and add the following code
<div *ngIf="book">
<h2>{{ book.name }} details!</h2>
<div><label>id: </label>{{ book.id }}</div>
<div>
<label>name: </label> <input [(ngModel)]="book.name" placeholder="name" />
</div>
<button (click)="goBack()">Back</button>
</div>
67
DATE:____/______/2023
C
font-weight: bold;
}
input {
height: 2em;
font-size: 1em;
padding-left: 0.4em;
}
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
}
<div>
<h1>404 Error</h1>
<h1>Page Not Found</h1>
</div>
68
DATE:____/______/2023
C
{ path: 'dashboard', component: DashboardComponent },
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'books', component: BookComponent },
{ path: 'detail/:id', component: BookDetailComponent },
{ path: '**', component: PageNotFoundComponent },
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
69
DATE:____/______/2023
C
export class AppComponent { title = 'Tour of Books';
}
<h1>{{title}}</h1>
<nav>
<a [routerLink]='["/dashboard"]' routerLinkActive="active">Dashboard</a>
<a [routerLink]='["/books"]' routerLinkActive="active">Books</a>
</nav>
<router-outlet></router-outlet>
17. Open app.component.css and add the following code
/* Master Styles */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
a{
cursor: pointer;
cursor: hand;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
70
DATE:____/______/2023
C
}
button:disabled {
background-color: #eee;
color: #aaa;
cursor: auto;
}
/* Navigation link styles */
nav a {
padding: 5px 10px;
text-decoration: none;
margin-right: 10px;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
nav a.active {
color: #039be5;
}
/* everywhere else */
*{
font-family: Arial, Helvetica, sans-serif;
}
18. Open styles.css under the src folder and add the following code
/* You can add global styles to this file, and also import other style files */
body{
padding:10px;
}
19. Open book.component.ts file in book folder and add the following code
import { Component, OnInit } from '@angular/core';
import { Book } from './book';
import { BookService } from './book.service';
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
71
DATE:____/______/2023
C
export class BookComponent implements OnInit {
books!: Book[];
errorMessage!: string;
constructor(private bookService: BookService) { }
getBooks() {
this.bookService.getBooks().subscribe({
next: books => this.books = books,
error:error => this.errorMessage = <any>error
})
}
ngOnInit(): void {
this.getBooks();
}
}
<h2>My Books</h2>
<ul class="books">
<li *ngFor="let book of books">
<span class="badge">{{ book.id }}</span> {{ book.name }}
</li>
</ul>
<div class="error" *ngIf="errorMessage">{{ errorMessage }}</div>
21. Save the files and check the output in the browser.
Output:
72
DATE:____/______/2023
C
b) Route Guards
Aim: Consider the same example used for routing. Add route guard to BooksComponent. Only
after logging in, the user should be able to access BooksComponent. If the user tries to give the
URL of Bookscomponent in another tab or window, or if the user tries to reload the
BooksComponent page, it should be redirected to LoginComponent.
Program:
1. Create a component named LoginComponent and add the following code to the login.component.html
file:
73
DATE:____/______/2023
C
3. Create user.ts file under login folder and add the following code to user.ts file:
74
DATE:____/______/2023
C
})
export class LoginService {
private isloggedIn = false;
getAllUsers(): Observable<User[]> {
return usersObservable;
}
isUserAuthenticated(username: string, password: string): Observable<boolean> {
return this.getAllUsers().pipe(
map(users => {
const Authenticateduser = users.find(user => (user.username === username) && (user.password ===
password));
if (Authenticateduser) {
this.isloggedIn = true;
} else {
this.isloggedIn = false;
}
return this.isloggedIn;
})
);
}
isUserLoggedIn(): boolean {
return this.isloggedIn;
}
}
5. Create another service class called login-guard.service inside login folder and add the following code:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { LoginService } from './login.service';
@Injectable({
providedIn: 'root'
})
export class LoginGuardService implements CanActivate {
constructor(private loginService: LoginService, private router: Router) { }
canActivate(): boolean {
if (this.loginService.isUserLoggedIn()) {
return true;
}
this.router.navigate(['/login']);
return false;
}
}
75
DATE:____/______/2023
76
DATE:____/______/2023
C
exports: [
RouterModule
]
})
export class AppRoutingModule { }
Output:
77
DATE:____/______/2023
C
c) Asynchronous Routing
Aim: Apply lazy loading to BookComponent. If lazy loading is not added to the demo, it has
loaded in 1.14 s. Observe the load time at the bottom of the browser console. Press F12 in the
browser and click the Network tab and check the Load time
Program:
1. Write the code given below in the book-routing.module.ts file inside book folder.
2. Create the book.module.ts file inside book folder and add the following code
78
DATE:____/______/2023
C
import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; const appRoutes:
Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: 'books', loadChildren: () => import('./book/book.module').then(m => m.BookModule) },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: BookDetailComponent} ,
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
79
DATE:____/______/2023
C
Output:
80
DATE:____/______/2023
C
d) Nested Routes
Aim: Implement Child Routes to a submodule.Nested Routes
Program:
1. Write the following code in app.module.ts.
81
DATE:____/______/2023
C
<nav>
<a [routerLink]='["/books"]' routerLinkActive="active">Books</a>
<a [routerLink]='["/books/dashboard"]' routerLinkActive="active">Dashboard</a>
</nav>
<router-outlet></router-outlet>
4. Write the below code in book.module.ts
import { NgModule } from '@angular/core';
import { BookComponent } from './book.component';
import { BookRoutingModule } from './book-routing.module';
import { FormsModule } from '@angular/forms';
import { BookDetailComponent } from '../book-detail/book-detail.component';
import { DashboardComponent } from '../dashboard/dashboard.component';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [ CommonModule, BookRoutingModule, FormsModule],
declarations: [BookComponent, BookDetailComponent, DashboardComponent]
})
export class BookModule { }
82
DATE:____/______/2023
C
<br/>
<h2>MyBooks</h2>
<ul class="books">
<li *ngFor="let book of books " (click)="gotoDetail(book)">
<span class="badge">{{book.id}}</span> {{book.name}}
</li>
</ul>
<div>
<router-outlet></router-outlet>
</div>
<div class="error" *ngIf="errorMessage">{{errorMessage}}</div>
<div *ngIf="book">
<h2>{{ book.name }} details!</h2>
<div><label>id: </label>{{ book.id }}</div>
<div>
83
DATE:____/______/2023
C
<label>name: </label> <input [(ngModel)]="book.name" placeholder="name" />
</div>
<button (click)="goBack()">Back</button>
</div>
9.Update book-detail.component.ts as below:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Book } from '../book/book';
import { BookService } from '../book/book.service';
@Component({
selector: 'app-book-detail',
templateUrl: './book-detail.component.html',
styleUrls: ['./book-detail.component.css'],
})
export class BookDetailComponent implements OnInit {
book!: Book;
error!: any;
constructor(
private bookService: BookService,
private route: ActivatedRoute
){}
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.bookService.getBook(params.get('id')).subscribe((book) => {
this.book = book ?? this.book;
});
});
}
goBack() {
window.history.back();
}
}
10. Update dashboard.component.html with below:
<h3>Top Books</h3>
<div class="grid grid-pad">
<div *ngFor="let book of books" (click)="gotoDetail(book)" class="col-1-4">
<div class="module book">
<h4>{{ book.name }}</h4>
</div>
</div>
</div>
84
DATE:____/______/2023
C
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Book } from '../book/book';
import { BookService } from '../book/book.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
books: Book[] = [];
constructor(
private router: Router,
private bookService: BookService) { }
ngOnInit(): void {
this.bookService.getBooks()
.subscribe(books => this.books = books.slice(1, 5));
}
gotoDetail(book: Book): void {
this.router.navigate(['/books/detail', book.id]);
}
}
12. Save the files and check the output in the browser.
Output:
85