MST Lab Manual
MST Lab Manual
`
CSE
INDEX
S.no Name Of The Experiment Page.No
LIMAT Page 2
MEAN STACK TECHNOLOGIES -II
`
CSE
LIMAT Page 3
MEAN STACK TECHNOLOGIES -II
`
CSE
85851554325460000 0_shared&collectionType=Course
Course Name: Angular JS
Module Name: Model Driven Forms or Reactive Forms
Create an employee registration form as a reactive form.
57
7b https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_33704702617536004000_shared?collectionId=lex_2
08585155432546000 00_shared&collectionType=Course
Course Name: Angular JS
Module Name: Custom Validators in Reactive Forms
Create a custom validator for an email field in the employee
7c registration form ( reactive form) 65
https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_33728128192769250000_shared?collectionId=lex_2
08585155432546000 00_shared&collectionType=Course
Course Name: Angular JS
Module Name: Custom Validators in Template Driven forms
Create a custom validator for the email field in the course
registration form. 69
8a https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_27688491925133280000_shared?collectionId=lex_2
08585155432546000 00_shared&collectionType=Course
Course Name: Angular JS
Module Name: Services Basics
Create a Book Component which fetches book details like id,
name and displays them on the page in a list format. Store the
8b book details in an array and fetch the data using a custom 74
service.
https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_32584403823635940000_shared?collectionId=lex_2
08585155432546000 00_shared&collectionType=Course
Course Name: Angular JS
Module Name: RxJS Observables
8c Create and use an observable in Angular.
77
https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_6209609363905256000_shared?collectionId=lex_20
85851554325460000 0_shared&collectionType=Course
Course Name: Angular JS
Module Name: Server Communication using HttpClient
Create an application for Server Communication using HttpClient
9a https://infyspringboard.onwingspan.com/web/en/viewer/web- 79
module/lex_auth_0127637395317063682615_shared?collectionI
d=lex_20858515543
254600000_shared&collectionType=Course
Course Name: Angular JS
Module Name: Communicating with different backend
services using Angular HttpClient
Create a custom service called ProductService in which Http class
81
is used to fetch data stored in the JSON files.
9b https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_4266333361795059700_shared?collectionId=lex_20
85851554325460000 0_shared&collectionType=Course
Course Name: Angular JS
Module Name: Routing Basics, Router Links 87
Create multiple components and add routing to provide navigation
LIMAT Page 4
MEAN STACK TECHNOLOGIES -II
`
CSE
between them.
https://infyspringboard.onwingspan.com/web/en/viewer/web-
10a module/lex_3782024852517635000_shared?collectionId=lex_20
85851554325460000 0_shared&collectionType=Course
Course Name: Angular JS
Module Name: Route Guards
Considering 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
96
10b URL of Bookscomponent in another tab or window, or if the user
tries
https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_30303325731876470000_shared?collectionId=lex_2
08585155432546000 00_shared&collectionType=Course
Course Name: Angular JS
Module Name: Asynchronous Routing
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
10c at the bottom of the browser console. Press F12 in the browser 104
and click the Network tab and check the Load time
https://infyspringboard.onwingspan.com/web/en/viewer/web-
module/lex_9878739890118246000_shared?collectionId=lex_20
85851554325460000 0_shared&collectionType=Course
Course Name: Angular JS
Module Name: Nested Routes
Implement Child Routes to a submodule.
https://infyspringboard.onwingspan.com/web/en/viewer/web- 109
10d module/lex_auth_012768043900444672140_shared?collectionId
=lex_208585155432
54600000_shared&collectionType=Course
Course Name: MongoDB Essentials - A Complete MongoDB
Guide
Module Name: Installing MongoDB on the local computer,
Create MongoDB Atlas Cluster
11a Install MongoDB and configure ATLAS 115
https://infyspringboard.onwingspan.com/web/en/viewer/video/lex
_auth_01281821437
313024030083_shared?collectionId=lex_auth_013177169294712
832113_shared&coll ectionType=Course
Course Name: MongoDB Essentials - A Complete MongoDB
Guide
Module Name: Introduction to the CRUD Operations
Write MongoDB queries to perform CRUD operations on
11b document using insert(), find(), update(), remove() 117
https://infyspringboard.onwingspan.com/web/en/viewer/video/lex
_auth_01281821874
166169630118_shared?collectionId=lex_auth_013177169294712
832113_shared&coll ectionType=Course
Course Name: MongoDB Essentials - A Complete MongoDB
Guide
Module Name: Create and Delete Databases and Collections
119
Write MongoDB queries to Create and drop databases and
12a collections.
https://infyspringboard.onwingspan.com/web/en/viewer/video/lex
LIMAT Page 5
MEAN STACK TECHNOLOGIES -II
`
CSE
_auth_01281821654
119219230121_shared?collectionId=lex_auth_013177169294712
832113_shared&coll ectionType=Course
Course Name: MongoDB Essentials - A Complete MongoDB 120
Guide
Module Name: Introduction to MongoDB Queries
Write MongoDB queries to work with records using
12b find(), limit(), sort(), createIndex(), aggregate().
https://infyspringboard.onwingspan.com/web/en/viewer/video/lex
_auth_01328908162
64519682505_shared?collectionId=lex_auth_0131771692947128
32113_shared&colle ctionType=Course
LIMAT Page 6
MEAN STACK TECHNOLOGIES -II
`
CSE
EXERCISE-1(a)
REQUIREMENTS DETAILS
LIMAT Page 7
MEAN STACK TECHNOLOGIES -II
`
CSE
Output:
PS C:\Users\SRK\Desktop\cseb rockers> npm install -g @angular/cli
PS C:\Users\SRK\Desktop\cseb rockers> Set-ExecutionPolicy -Scope CurrentUser - ExecutionPolicy
RemoteSigned
PS C:\Users\SRK\Desktop\cseb rockers> ng new my-app
Node.js version v19.8.1 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For
more information, please see https://nodejs.org/en/about/releases/.? Would you like to add Angular routing?
Yes? Which stylesheet format would you like to use? Less [ http://lesscss.org]
CREATE my-app/angular.json (2874 bytes) CREATE my-
app/package.json (1037 bytes) CREATE my-app/README.md
(1059 bytes) CREATE my-app/tsconfig.json (901 bytes)
CREATE my-app/.editorconfig (274 bytes) CREATE my-
LIMAT Page 8
MEAN STACK TECHNOLOGIES -II
`
CSE
LIMAT Page 9
MEAN STACK TECHNOLOGIES -II
`
CSE
Exercise-1(b)
Course Name: Angular JS
Module Name: Components and Modules Create a new component called hello and render Hello Angular
on the page.
Process :
Step 1 - Test the default app
In this step, after you download the default starting app, you build the default Angular app. This confirms
that your development environment has what you need to continue the tutorial.
In the Terminal pane of your IDE:
1. In your project directory, navigate to the first-app directory.
2. Run this command to install the dependencies needed to run the app.
npm install
3. Run this command to build and serve the default app.
ng serve
The app should build without errors.
4. In a web browser on your development computer, open http://localhost:4200.
5. Confirm that the default web site appears in the browser.
6. You can leave ng serve running as you complete the next steps.
Step 2 - Review the files in the project
In this step, you get to know the files that make up a default Angular app. In the Explorer
pane of your IDE:
1. In your project directory, navigate to the first-app directory.
2. Open the src directory to see these files.
a. In the file explorer, find the Angular app files (/src).
i. index.html is the app's top level HTML template.
ii. style.css is the app's top level style sheet.
iii. main.ts is where the app start running.
iv. favicon.ico is the app's icon, just as you would find in any web site.
b. In the file explorer, find the Angular app's component files (/app).
i. app.component.ts is the source file that describes the app- root component.
This is the top-level Angular component in the app. A component is the basic building
block of an Angular application. The component description includes the component's
code, HTML template, and styles, which can be described in this file, or in separate
files.
LIMAT Page 10
MEAN STACK TECHNOLOGIES -II
`
CSE
In this app, the styles are in a separate file while the component's code and HTML
template are in this file.
LIMAT Page 11
MEAN STACK TECHNOLOGIES -II
`
CSE
without error and displays Hello world in the title and body of your app:
Program: Helloworld.js
Index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Default</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:ital,wght@0,40
0;0,700;1,400;1,700&display=swap" rel="stylesheet">
</head>
<body>
<app-root></app-root>
</body>
</html>
Main.ts:
import { bootstrapApplication,provideProtractorTestingSupport } from '@angular/platfor m-browser';
import { AppComponent } from './app/app.component';
providers: [provideProtractorTestingSupport()]})
.catch(err => console.error(err));
Style.css:
{
margin: 0;
LIMAT Page 12
MEAN STACK TECHNOLOGIES -II
`
CSE
padding: 0;
}
body {
font-family: 'Be Vietnam Pro', sans-serif;
}
:root {
--primary-color: #605DC8;
--secondary-color: #8B89E6;
--accent-color: #e8e7fa;
--shadow-color: #E8E8E8;
}
button.primary { padding: 10px;
border: solid 1px var(--primary-color); background:
var(--primary-color); color: white;
border-radius: 8px;
}
App.component.css
:host {
--content-padding: 10px;
}
header { display: block; height:
60px;
padding: var(--content-padding);
box-shadow: 0px 5px 25px var(--shadow-color);
}
.content {
padding: var(--content-padding);
}
App.component.ts
import { Component } from '@angular/core';
@Component({ selector: 'app-root',
standalone: true, imports: [],
template: `<h1>Hello</h1>`, styleUrls:
['./app.component.css'],
})
export class AppComponent {
LIMAT Page 13
MEAN STACK TECHNOLOGIES -II
`
CSE
title = 'default';}
Output:
~/projects/qqsjdl--run
❯ npm install --legacy-peer-deps && npm start
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use
Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-
random for details.
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated request@2.88.2: request has been deprecated, see
https://github.com/request/request/issues/3142
npm WARN deprecated protractor@7.0.0: We have news to share - Protractor is deprecated and will reach
end-of-life by Summer 2023. To learn more and find out about other options please refer to this post on
the Angular blog. Thank you for using and contributing to Protractor. https://goo.gle/state-of-e2e-in-
angular added 1062 packages in 10s
104 packages are looking for funding run `npm fund`
for details
> angular.io-example@0.0.0 start
> ng serve
✔ Browser application bundle generation complete.
Initial Chunk Files | Names | Raw Size vendor.js |
vendor | 1.98 MB |
polyfills.js | polyfills | 333.17 kB | styles.css,
styles.js | styles | 231.00 kB | runtime.js |
runtime | 6.53 kB | main.js | main | 4.11
kB |
| Initial Total | 2.54 MB
LIMAT Page 14
MEAN STACK TECHNOLOGIES -II
`
CSE
LIMAT Page 15
MEAN STACK TECHNOLOGIES -II
`
CSE
Exercise-1(c)
Course Name: Angular JS Module.
Module Name: Elements of Template Add an event to the hello component template and when it is
clicked, it should change the course Name.
hello.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({ selector: 'app-hello',
templateUrl: "./hello.component.html", styleUrls:
['./hello.component.css']
})
export class HelloComponent implements OnInit { courseName =
"MSD";
constructor() { } ngOnInit() {
}
changeName() { this.courseName = "CSE";
}
}
hello.component.html:
<h1>Welcome</h1>
<h2>Course Name: {{ courseName }}</h2>
<button><p (click)="changeName()">Click here to change</p></button>
hello.component.css:
p{
color:rgb(255, 60, 0); font-size:20px;
}
Output:
PS C:\Users\CSE\Desktop\angular\MyApp\src\app> ng serve --open --port 3000
✔ Browser application bundle generation complete.
al Chunk Files | Names | Raw Size vendor.js |
vendor | 2.28 MB | polyfills.js | polyfills |
333.15 kB | styles.css, styles.js | styles | 230.44
kB | main.js | main | 8.79 kB | runtime.js |
runtime | 6.51 kB |
LIMAT Page 17
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-1(d)
Course Name: Angular JS
Module Name: Structural Directives - ngIf
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
Directives are used to change the behavior of components or elements. It can be used in the form of
HTML attributes.
You can create directives using classes attached with @Directive decorator which adds metadata to the
class.
Why Directives?
It modify the DOM elements
It creates reusable and independent code
It is used to create custom elements to implement the required functionality
Types of Directives
There are three types of directives available in Angular
Components
Components are directives with a template or view.
@Component decorator is actually @Directive with templates
Structural Directives
A Structural directive changes the DOM layout by adding and removing DOM elements.
Syntax: *directive-name=expression
Angular has few built-in structural directives such as:
o ngIf
o ngFor
o ngSwitch
ngIf: ngIf directive renders components or elements conditionally based on whether or not an expression is
true or false.
Syntax:
1. *ngIf = "expression"
Open already created app and do the required modifications in app.component.ts file
import { Component } from '@angular/core';
LIMAT Page 18
MEAN STACK TECHNOLOGIES LAB MANUAL
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls:
['./app.component.css'],
})
app.component.html
<div *ngIf="!submitted">
<fom>
<label>User Name</label>
<inpt 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>
<div *ngIf="submitted">
<div *ngIf="isAuthenticated; else failureMsg">
<h4>Welcome {{ userName }}</h4>
</div>
<ng-template #failureMsg>
<h4>Invalid Login !!! Please try again...</h4>
LIMAT Page 19
</ng-template> MEAN STACK TECHNOLOGIES LAB MANUAL
<button type="button" (click)="submitted = false">Back</button>
</div>
app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule
} from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent], imports:
[BrowserModule], providers: [],
bootstrap: [AppComponent],
})export class AppModule {}
index.tml
<!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>
<approot></app-root>
</body>
</html>
Save the files and the check the output in browser
Output:
If the usename and password are correct console will display this output.
LIMAT Page 20
MEAN STACK TECHNOLOGIES LAB MANUAL
If the username and password are incorrect Invalid Login !! will be displayed.
LIMAT Page 21
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-2(a)
Course Name: Angular JS
Module Name: Structural Directives - ngIf
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
• Directives are used to change the behavior of components or elements. It can be used in
the form of HTML attributes.
• You can create directives using classes attached with @Directive decorator which adds
metadata to the class.
Why Directives?
• It modify the DOM elements
• It creates reusable and independent code
• It is used to create custom elements to implement the required functionality
Types of Directives
There are three types of directives available in Angular
Components
• Components are directives with a template or view.
• @Component decorator is actually @Directive with templates
Structural Directives
LIMAT Page 22
MEAN STACK
• A Structural directive changesTECHNOLOGIES
the DOM layout LABbyMANUAL
adding and removing DOM
elements.
Syntax: *directive-name=expression
• Angular has few built-in structural directives such as:
o ngIf
o ngFor
o ngSwitch
ngIf: ngIf directive renders components or elements conditionally based on whether or not
an expression is true or false.
Syntax:
1. *ngIf = "expression"
Open already created app and do the required modifications in app.component.ts file
import { Component } from '@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css'],
})
@NgModule({
declarations: [AppComponent], imports: [BrowserModule], providers: [],
bootstrap: [AppComponent],
})export class AppModule {}
index.tml
<!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>
<approot></app-root>
</body>
</html>
• Save the files and the check the output in browser
LIMAT Page 24
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-2(b)
LIMAT Page 25
MEAN'app-root',
@Component({ selector: STACK TECHNOLOGIES LAB MANUAL
templateUrl: './app.component.html', styleUrls: ['./app.component.css']
})
export class AppComponent { courses: any[] = [
{ id: 1, name: 'TypeScript' },
{ id: 2, name: 'Angular' },
{ id: 3, name: 'Node JS' },
{ id: 1, name: 'TypeScript' }
];
}
2. Write the below-given code in app.component.html
<ul>
<li *ngFor="let course of courses; let i = index">
{{ i }} - {{ course.name }}
</li>
</ul>
3. Save the files and check the output in the browser
import { Component } from '@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css']
})
export class AppComponent { courses: any[] = [
{ id: 1, name: 'TypeScript' },
{ id: 2, name: 'Angular' },
{ id: 3, name: 'Node JS' },
{ id: 1, name: 'TypeScript' }
];
}
Output:
LIMAT Page 26
MEAN STACK TECHNOLOGIES LAB MANUAL
LIMAT Page 27
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-2(c)
Course Name: Angular JS
Module Name: ngSwitch
Display the correct option based on the value passed to ngSwitch directive.
App.componet.ts
import { Component } from '@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css'],
})
export class AppComponent { c=0;
nextChoice(){ this.c++;
if(this.c>6){
this.c=0;} }}
App.component.html
<h4>current choice is {{c}}</h4>
<div [ngSwitch]="c">
<p *ngSwitchCase="0">Start </p>
<p *ngSwitchCase="1">HTML</p>
<p *ngSwitchCase="2">CSS</p>
<p *ngSwitchCase="3">Javascript</p>
<p *ngSwitchCase="4">Typescript</p>
<p *ngSwitchCase="5">Angular</p>
<p *ngSwitchCase="6">Exit</p>
</div>
<div>
<button (click)="nextChoice()"> Next</button>
</div>
Output:
LIMAT Page 28
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-2(d)
Course Name: Angular JS
Module Name: Custom Structural Directive
Create a custom structural directive called 'repeat' which should repeat the element given a
number of times.
Step-1:Generate a new directive by using Directive method D:\MyApp> ng generate
directive repeat
This will create two files under the src\app folder with names repeat.directive.ts and
repeat.directive.spec.ts (this is for testing). Now the app folder structure will look as shown
below.
Step-2: app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from
'@angular/core';
import { AppComponent } from './app.component'; import { RepeatDirective } from
'./repeat.directive';
@NgModule({ declarations: [ AppComponent, RepeatDirective],
imports: [ BrowserModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
repeat.directive.ts
import { Directive ,TemplateRef,ViewContainerRef,Input} from '@angular/core';
@Directive({
selector: '[appRepeat]'
})
export class RepeatDirective {
constructor(private templatRref:TemplateRef<any>,private
viewContainer:ViewContainerRef)
{}
LIMAT Page 29
MEAN STACK TECHNOLOGIES
@Input() set appRepeat(count:number){ LAB MANUAL
for(let i=0;i<count;i++){
this.viewContainer.createEmbeddedView(this.templatRref);
}
}
}
App.component.html
<h3>Structural Directive with exportAs property</h3>
<ng-template appRepeat #rd="repeat" #ct="changeText">
<p>I am being repeated...</p>
</ng-template>
<button (click)="rd.repeatElement(5)">Repeat Element</button>
<button (click)="ct.changeElementText(5)">Change Text</button>
Output:
LIMAT Page 30
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-3(a)
Module Name: Attribute directives(ngStyle)
Apply multiple CSS properties to a paragraph in a component using ngStyle.
Attribute directives change the appearance/behavior of a component/element. Following are
built-in attribute directives:
• ngStyle
• ngClass
This directive is used to modify a component/element’s style. You can use the following
syntax to set a single CSS style to the element which is also known as style binding
[style.<cssproperty>] = "value"
If there are more than one CSS styles to apply, you can use ngStyle attribute. Now apply the
following modifications in the files of MyApp. app.component.ts
import { Component } from '@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css'],
})
export class AppComponent { colorName = 'blue'; fontWeight = 'bold';
borderStyle = '1px solid black';}
app.component.html
LIMAT Page 31
<p MEAN STACK TECHNOLOGIES LAB MANUAL
[ngStyle]="{
color: colorName,
'font-weight': fontWeight, borderBottom: borderStyle
}">
Demo for attribute directive ngStyle
</p>
Save the changes to files and check the browser for output.
Output:
Exercise-3(b)
Module Name: ngClass
Apply multiple CSS classes to the text using ngClass directive.
It allows you to dynamically set and change the CSS classes for a given DOM element. Use the following
syntax to set a single CSS class to the element which is also known as class binding.
[class.<css_class_name>] = "property/value"
If you have more than one CSS classes to apply, then you can go for ngClass syntax.
Syntax:[ngClass] = "{css_class_name1 : Boolean expression, css_class_name2: Boolean
expression, ……}"
1. 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 { isBordered = true;}
Here we created a Boolean expression isBordered to evaluate the border style for html pag
2. Write the below-given code in app.component.html.
<div [ngClass]="{bordered: isBordered}"> Border {{ isBordered ? "ON" : "OFF" }}
</div>
3. In app.component.css, add the following CSS class.
.bordered {
LIMAT Page 32
MEAN
border: 1px dashed black; STACK TECHNOLOGIES
background-color: #eee; LAB MANUAL
}
You can Save the changes and check the browser for output.
Output:
You can create a custom attribute directive when there is no built-in directive available for the required
functionality. For Example, consider the following problem statement:
To create a custom attribute directive, we need to create a class annotated with @Directive
@Directive({
})
class MyDirective { }
Example:
1.Generate a directive called 'message' using the following command D:\MyApp> ng
generate directive message
This will create two files under the src\app folder with the names message.directive.ts and
message.directive.spec.ts (this is for testing). Now the app folder structure will look as shown below:
LIMAT Page 33
MEAN STACK TECHNOLOGIES LAB MANUAL
It also adds message directive to the root module i.e., app.module.ts to make it available to the entire module
as shown below
2. 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 { }
3. Open the message.directive.ts file and add the following code
import { Directive, ElementRef, Renderer2, HostListener, Input } from '@angular/core';
@Directive({ selector: '[appMessage]',
})
export class MessageDirective {
@Input('appMessage') message!: string;
constructor(private el: ElementRef, private renderer: Renderer2) { renderer.setStyle(el.nativeElement,
'cursor', 'pointer');}
@HostListener('click') onClick() { this.el.nativeElement.innerHTML =
LIMAT Page 34
MEAN STACK TECHNOLOGIES
this.message; this.renderer.setStyle(this.el.nativeElement, LAB'red');
'color', MANUAL
}
}
4. Write the below-given code in app.component.html
<h3>Attribute Directive</h3>
<p [appMessage]="myMessage">Click Here</p>
5. Add the following CSS styles to the app.component.css file h3 {
color: #369;
font-family: Arial, Helvetica, sans-serif; font-size: 250%;
}
p{
color: #ff0080;
font-family: Arial, Helvetica, sans-serif; font-size: 150%;
}
6. Add the following 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 {
myMessage = 'Hello, I am from attribute directive';
}
Save the changes and check the browser for output.
Output:
LIMAT Page 35
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-4(a)
LIMAT Page 36
Course Name: Angular JS MEAN STACK TECHNOLOGIES LAB MANUAL
Module Name: Property Binding .(Binding image with class property using property binding.)
1. Write the following code in app.component.ts as shown below import {
Component } from '@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css']
})
export class AppComponent { imgUrl = 'assets/imgs/logo.png';
}
Create a folder named "imgs" inside src/assets and place a logo.png file inside it 2.Write the following code in
app.component.html as shown below
<img [src]='imgUrl'>
3.Save the files and check the output in the browser
LIMAT Page 37
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-4(b)
Module Name: Attribute Binding
Binding colspan attribute of a table element to the class property to display the following output
1. Writethebelow-givencodeinapp.component.ts
import{Component}from'@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css']
})
exportclassAppComponent{ colspanValue='2';
}
2. Writethe below-given code in app.component.html
<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>
3. Savethefilesandchecktheoutputinthebrowser
OUTPUT:-
LIMAT Page 38
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-4(c)
Module Name: Style and Event Binding
Binding an element using inline style and user actions like entering text in input fields.
1.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';
}
2.Write the below-given code in app.component.html
<input type="text" [(ngModel)]="name"> <br/>
<div>Hello , {{ name }}</div>
3.Write the below-given code in app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component';
@NgModule({ declarations: [ AppComponent
],
imports: [ BrowserModule, FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
4.Save the files and check the output in the browser
Output:
LIMAT Page 39
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-5(a)
Module Name: Built in Pipes .Displaying the product code in lowercase and product name in uppercase using
built-in pipes. The output is as shown below
1.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 { title = 'product details'; productCode = 'PROD_P001'; productName = 'Laptop';
}
2.Write the below-given code in app.component.html
<h3> {{ title | titlecase}} </h3>
<table style="text-align:left">
<tr>
<th> Product Code </th>
<td> {{ productCode | lowercase }} </td>
</tr>
<tr>
<th> Product Name </th>
<td> {{ productName | uppercase }} </td>
</tr>
</table>
3.Save the files and check the output in the browser
LIMAT Page 40
OUTPUT:- MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-5(b)
Module Name: Passing Parameters to Pipes
Aplying built-in pipes with parameters to display product details. The output is as shown below
We have applied currency pipe to product price with locale setting as 'fr' i.e., French. According to the French
locale, the currency symbol will be displayed at the end of the price as shown in the above output.
1. Write the below-given code in app.component.ts
1.import { Component } from '@angular/core';
@Component({ selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css']
})
export class AppComponent { title = 'product details'; productCode = 'PROD_P001';
productName = 'Apple MPTT2 MacBook Pro'; productPrice = 217021;
purchaseDate = '1/17/2018'; productTax = '0.1';
productRating = 4.92;
}
1.
2.Write the below-given code in app.component.html
<h3> {{ title | titlecase}} </h3>
<table style="text-align:left">
<tr>
LIMAT Page 41
<th> Product Code </th> MEAN STACK TECHNOLOGIES LAB MANUAL
<td> {{ productCode | slice:5:9 }} </td>
</tr>
<tr>
<th> Product Name </th>
<td> {{ productName | uppercase }} </td>
</tr>
<tr>
<th> Product Price </th>
<td> {{ productPrice | currency: 'INR':'symbol':'':'fr' }} </td>
</tr>
<tr>
<th> Purchase Date </th>
<td> {{ purchaseDate | date:'fullDate' | lowercase}} </td>
</tr>
<tr>
<th> Product Tax </th>
<td> {{ productTax | percent : '.2' }} </td>
</tr>
<tr>
<th> Product Rating </th>
<td>{{ productRating | number:'1.3-5'}} </td>
</tr>
</table>
3.Write the below-given code in app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';
import { AppComponent } from './app.component'; import { registerLocaleData } from '@angular/common';
import localeFrench from '@angular/common/locales/fr'; registerLocaleData(localeFrench);
@NgModule({ declarations: [ AppComponent
],
imports: [ BrowserModule
],
providers: [],
LIMAT Page 42
bootstrap: [AppComponent]MEAN STACK TECHNOLOGIES LAB MANUAL
})
export class AppModule { }
4. Save the 昀椀les and check the output in the browser
Output:
Exercise-5(c)
Module Name: Passing Parameters to Pipes
Loading CourseslistComponent in the root component when a user clicks on the View courses list button as
shown below
1. Create a component called courses list using the following CLI command
D:\MyApp>ng generate component coursesList
The above command will create a folder with name courses-list with the following files
• courses-list.component.ts
• courses-list.component.html
• courses-list.component.css
• courses-list.component.spec.ts
2. CoursesListComponent class will be added in the app.module.ts file import
{ BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
LIMAT Page 43
MEAN
import { CoursesListComponent STACK
} from TECHNOLOGIES LAB MANUAL
'./courses-list/courses-list.component';
@NgModule({ declarations: [ AppComponent, CoursesListComponent
],
imports: [ BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
3.Write the below-given code in courses-list.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-courses-list',
templateUrl: './courses-list.component.html', styleUrls: ['./courses-list.component.css']
})
export class CoursesListComponent { courses = [
{ courseId: 1, courseName: "Node JS" },
{ courseId: 2, courseName: "Typescript" },
{ courseId: 3, courseName: "Angular" },
{ courseId: 4, courseName: "React JS" }
];
}
4.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>
LIMAT Page 44
<td>{{ course.courseNameMEAN
}}</td>STACK TECHNOLOGIES LAB MANUAL
</tr>
</tbody>
</table>
5.Add the following code in courses-list.component.css
tr{
text-align:center;
}
6.Write the below-given code in app.component.html
<h2>Popular Courses</h2>
<button (click)="show = true">View Courses list</button><br /><br />
<div *ngIf="show">
<app-courses-list></app-courses-list>
</div>
7.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 { show!: boolean; }
8. Save the and check the output in the browser
OUTPUT:-
LIMAT Page 45
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-6(a)
Module Name: Passing data from Container Component to Child Component
Create an AppComponent that displays a dropdown with a list of courses as values in it. Create another
component called the CoursesList component and load it in AppComponent which should display the course
details. When the user selects a course from the.
Steps:
LIMAT Page 46
MEAN STACK
1. Open the courses-list.component.ts TECHNOLOGIES
file created in the exampleLAB MANUAL
of nested components and add the following
code
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-courses-list',
templateUrl: './courses-list.component.html', styleUrls: ['./courses-list.component.css'],
})
export class CoursesListComponent { courses = [
{ courseId: 1, courseName: 'Node JS' },
{ courseId: 2, courseName: 'Typescript' },
{ courseId: 3, courseName: 'Angular' },
{ courseId: 4, courseName: 'React JS' },
];
course!: any[];
@Input() set cName(name: string) { this.course = [];
for (var i = 0; i < this.courses.length; i++) { if (this.courses[i].courseName === name) {
this.course.push(this.courses[i]);
}
}
}
}
2.Open courses-list.component.html and add the following code
<table border="1" *ngIf="course.length > 0">
<thead>
<tr>
<th>Course ID</th>
<th>Course Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let c of course">
<td>{{ c.courseId }}</td>
<td>{{ c.courseName }}</td>
LIMAT Page 47
</tr> MEAN STACK TECHNOLOGIES LAB MANUAL
</tbody>
</table>
3.Add the following in app.component.html
<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>
4.Add the following in app.component.ts
import { Component } from '@angular/core';
@Component({ selector: 'app-root',
styleUrls: ['./app.component.css'], templateUrl: './app.component.html'
})
export class AppComponent { name!: string;
}
Output:
LIMAT Page 48
Exercise-6(b) MEAN STACK TECHNOLOGIES LAB MANUAL
Module Name: Passing data from Child Component to ContainerComponent
Create an AppComponent that loads another component called the CoursesList component. Create another
component called CoursesListComponent which should display the courses list in a table along with a register
.button in each row. When a user clicks on the.
Steps:
1.Open the courses-list.component.ts file created in the previous example and add the following code
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-courses-list',
templateUrl: './courses-list.component.html', styleUrls: ['./courses-list.component.css']
})
export class CoursesListComponent {
@Output() registerEvent = new EventEmitter<string>(); courses = [
{ courseId: 1, courseName: 'Node JS' },
{ courseId: 2, courseName: 'Typescript' },
{ courseId: 3, courseName: 'Angular' },
{ courseId: 4, courseName: 'React JS' }];
register(courseName: string) { this.registerEvent.emit(courseName);
}}
2.Open courses-list.component.html 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>
LIMAT Page 49
MEAN STACK TECHNOLOGIES LAB MANUAL
<td><button (click)="register(course.courseName)">Register</button></td>
</tr>
</tbody>
</table>
3.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>
4.Add the following 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 { message!: string; courseReg(courseName: string) {
this.message = `Your registration for ${courseName} is successful`;
}
}
Output:
LIMAT Page 50
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-6(c)
Module Name: Shadow DOM
Apply ShadowDOM and None encapsulation modes to components.
Shadow DOM is a web components standard by W3C. It enables encapsulation for DOM tree and styles.
Shadow DOM hides DOM logic behind other elements and confines styles only for that component.
For example, in an Angular application, n number of components will be created and each component will
have its own set of data and CSS styles. When these are integrated, there is a chance that the data and styles
may be applied to the entire application. Shadow DOM encapsulates data and styles for each component to not
flow through the entire application
In the below example shown, each component is having its own styles defined and they are confined to
themselves:
Steps:
1. Create a component called First using the following CLI command
1.D:\MyApp>ng generate component first
2.Write the below-given code in first.component.css
1..cmp {
2.padding: 6px;
3.margin: 6px;
4.border: blue 2px solid; 5. }
3. Write the below-given code in first.component.html
1. <div class="cmp">First Component</div>
4. Create a component called Second using the following CLI command
1. D:\MyApp>ng generate component second
5. Write the below-given code in second.component.css
1..cmp {
LIMAT Page 51
2.border: green 2px solid; MEAN STACK TECHNOLOGIES LAB MANUAL
3.padding: 6px;
4.margin: 6px; 5. }
6. Write the below-given code in second.component.html
1. <div class="cmp">Second Component</div>
7. Write the below-given code in second.component.ts
1.import { Component, ViewEncapsulation } from '@angular/core';
2.@Component({
3.selector: 'app-second',
4.templateUrl: './second.component.html',
5.styleUrls: ['./second.component.css'],
6.encapsulation: ViewEncapsulation.ShadowDom 7. })
8. export class SecondComponent { 9. }
8. Write the below-given code in app.component.css
1..cmp {
2.padding: 8px;
3.margin: 6px;
4.border: 2px solid red; 5. }
9. Write the below-given code in app.component.html
1.<h3>CSS Encapsulation with Angular</h3>
2.<div class="cmp">
3.App Component
4.<app-first></app-first>
5.<app-second></app-second>
6.</div>
10. Save the files and check the output in the browser
Output:
LIMAT Page 52
ViewEncapsulation.None MEAN STACK TECHNOLOGIES LAB MANUAL
1. Set ViewEncapsulation to none mode in app.component.ts file
1.import { Component, ViewEncapsulation } from '@angular/core';
2.@Component({
3.selector: 'app-root',
4.styleUrls: ['./app.component.css'],
5.templateUrl: './app.component.html',
6.encapsulation: ViewEncapsulation.None 7. })
8. export class AppComponent {}
2. Set ViewEncapsulation to none mode in second.component.ts file
1. import { Component, ViewEncapsulation } from '@angular/core'; 2.
3.@Component({
4.selector: 'app-second',
5templateUrl: './second.component.html',
6.styleUrls: ['./second.component.css'],
7encapsulation: ViewEncapsulation.None 8. })
9. export class SecondComponent { 10.
11}
2. Save the files and check the output in the browser
Output:
LIMAT Page 53
MEAN STACK TECHNOLOGIES LAB MANUAL
LIMAT Page 54
14.OnDestroy { MEAN STACK TECHNOLOGIES LAB MANUAL
15.data = 'Angular';
16.ngOnInit() {
17.console.log('Init');
18.}
19.ngDoCheck(): void {
20.console.log('Change detected');
21.}
22.ngAfterContentInit(): void {
23.console.log('After content init');
24.}
25.ngAfterContentChecked(): void {
26.console.log('After content checked');
27.}
28.ngAfterViewInit(): void {
29.console.log('After view init');
30.}
31.ngAfterViewChecked(): void {
32.console.log('After view checked');
33.}
34.ngOnDestroy(): void {
35.console.log('Destroy');
36.}
37. }
2. Write the below-given code in app.component.html
1.<div>
2.<h1>I'm a container component</h1>
3.<input type="text" [(ngModel)]="data" />
4.<app-child [title]="data"></app-child>
5.</div> 6.
3. Write the below-given code in child.component.ts
1.import { Component, OnChanges, Input } from '@angular/core';
2.@Component({
LIMAT Page 55
3.selector: 'app-child', MEAN STACK TECHNOLOGIES LAB MANUAL
4.templateUrl: './child.component.html',
5.styleUrls: ['./child.component.css'] 6. })
7.export class ChildComponent implements OnChanges {
8.@Input() title!: string;
9.ngOnChanges(changes: any): void {
10.console.log('changes in child:' + JSON.stringify(changes));
11. }
12. }
4. Write the below-given code in child.component.html
1. <h2>Child Component</h2> 2. <h2>{{title}}</h2>
5.Ensure FormsModule is present in the imports section of the AppModule.
6.Save the files and check the output in the browser
Output:
LIMAT Page 56
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-7(a)
Module Name: Template Driven Forms
Create a course registration form as a template-driven form. Steps:
1. Create course.ts file under the course-form folder and add the following code
export class Course {
constructor(
public courseId: number,
public courseName: string,
public duration: string 6. ) { }
}
LIMAT Page 58
<input type="text" MEAN STACK TECHNOLOGIES
class="form-control" LAB MANUAL
required [(ngModel)]="course.courseName" name="name"
#name="ngModel">
<div [hidden]="name.valid || name.pristine" class="alert alert-danger">
Course Name is required
</div>
</div>
<div class="form-group">
<label for="duration">Course Duration</label>
<input type="text" class="form-control" required [(ngModel)]="course.duration" name="duration"
#duration="ngModel">
<div [hidden]="duration.valid || duration.pristine" class="alert alert-danger">
Duration is required
</div>
</div>
<button type="submit" class="btn btn-default"
[disabled]="!courseForm.form.valid">Submit</button>
<button type="button" class="btn btn-default" (click)="courseForm.reset()">New Course</button>
</form>
</div>
<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">Course ID</div>
<div class="col-xs-9 pull-left">{{ course.courseId }}</div>
</div>
<div class="row">
<div class="col-xs-3">Course Name</div>
<div class="col-xs-9 pull-left">{{ course.courseName }}</div>
</div>
<div class="row">
<div class="col-xs-3">Duration</div>
<div class="col-xs-9 pull-left">{{ course.duration }}</div>
LIMAT Page 59
</div> MEAN STACK TECHNOLOGIES LAB MANUAL
<br>
<button class="btn btn-default" (click)="submitted=false">Edit</button>
</div>
</div>
6. Write the below-given code in course-form.component.css
input.ng-valid[required] {
border-left: 5px solid #42A948; /* green */
}
input.ng-dirty.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
Write the below-given code in app.component.html
<app-course-form></app-course-form>
Remember to import FormsModule in app.module.ts.
Save the files and check the output in the browser
Output:
LIMAT Page 60
MEAN STACK TECHNOLOGIES
EXercise-7(b) LAB MANUAL
Module Name: Model Driven Forms or Reactive Forms Create an employee registration form as a reactive
form.
Steps:
1. 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 './registration-form/registration- form.component';
@NgModule({
declarations: [
AppComponent,
RegistrationFormComponent ],
imports: [
BrowserModule,
ReactiveFormsModule ],
providers: [],
bootstrap: [AppComponent] })
export class AppModule { }
2. Create a component called RegistrationForm using the following CLI command
ng generate component RegistrationForm
3. Add the following code in the registration-form.component.ts file
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-registration-form',
templateUrl: './registration-form.component.html',
styleUrls: ['./registration-form.component.css'] })
export class RegistrationFormComponent implements OnInit {
registerForm!: FormGroup;
submitted!:boolean;
LIMAT Page 61
MEAN FormBuilder)
constructor(private formBuilder: STACK TECHNOLOGIES
{} LAB MANUAL
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
address: this.formBuilder.group({
street: [],
zip: [],
city: []
})
});
}
}
4. 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 ale
danger">
Firstname field is invalid.
<p *ngIf="registerForm.controls['firstName'].errors?.['required']">
This field is required! 11. </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! 21. </p>
LIMAT Page 62
</div> MEAN STACK TECHNOLOGIES LAB MANUAL
</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>
<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>
5. 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 */
LIMAT Page 63
} MEAN STACK TECHNOLOGIES LAB MANUAL
4. Write the below-given code in app.component.html
1. <app-registration-form></app-registration-form>
7. Save the files and check the output in the browser.
Output:
LIMAT Page 64
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-7(c)
Module Name: Custom Validators in Reactive Forms
Create a custom validator for an email field in the employee registration form ( reactive form)
Steps:
1. Write a separate function in registration-form.component.ts for custom validation as shown below.
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-registration-form',
templateUrl: './registration-form.component.html',
styleUrls: ['./registration-form.component.css'] })
export class RegistrationFormComponent implements OnInit { 1
registerForm!: FormGroup;
submitted!:boolean;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['',Validators.required],
lastName: ['', Validators.required],
address: this.formBuilder.group({
street: [],
zip: [],
city: []
}),
email: ['',[Validators.required,validateEmail]] 24. });
}
}
function validateEmail(c: FormControl): any {
let EMAIL_REGEXP = /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA- Z]{2,5})$/;
return EMAIL_REGEXP.test(c.value) ? null : {
emailInvalid: {
LIMAT Page 65
message: "Invalid Format!" MEAN STACK TECHNOLOGIES LAB MANUAL
}
};
}
2. Add HTML controls for the email field in the registration-form.component.html file as shown below
<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! 11. </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! 21. </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>
LIMAT Page 66
MEAN STACK TECHNOLOGIES LAB MANUAL
<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']">
{{ 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.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>
<p>Email: {{ registerForm.get('email')?.value }}</p>
</div>
LIMAT Page 67
MEAN STACK TECHNOLOGIES LAB MANUAL
2. Save the files and check the output in the browser
Output:
LIMAT Page 68
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-8(a)
Course Name: Angular JS
Module Name: Custom Validators in Template Driven forms
Create a custom validator for the email field in the course registration form.
1. Write the code given below in course.ts
export class Course { constructor(
public courseId: number, public courseName:
string, public duration: string, public email:
string
){}
}
2. In the course-form.component.ts file, pass a default value to the email field as shown below
import { Component } from '@angular/core'; import { Course } from
'./course';
@Component({
selector: 'app-course-form',
templateUrl: './course-form.component.html', styleUrls: ['./course-
form.component.css']
})
export class CourseFormComponent {
course: Course = new Course(1, 'Angular 2', '4 days', 'james@gmail.com'); submitted = false;
onSubmit() { this.submitted = true; }
}
3. Create a file with the name email.validator.ts under the course-form folder to implement
custom validation functionality for the email field.
import { Directive } from '@angular/core';
import { NG_VALIDATORS, FormControl, Validator } from '@angular/forms';
@Directive({
selector: '[validateEmail]', providers: [
{ provide: NG_VALIDATORS, useExisting: EmailValidator, multi: true },
],
LIMAT Page 69
}) MEAN STACK TECHNOLOGIES LAB MANUAL
export class EmailValidator implements Validator { validate(control: FormControl):
any {
const emailRegexp =
/^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/;
if (!emailRegexp.test(control.value)) { return { emailInvalid:
'Email is invalid' };
}
return null;
}
}
4. Add EmailValidator class in the root module i.e., app.module.ts as shown below
import { BrowserModule } from '@angular/platform-browser'; import { NgModule
} from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CourseFormComponent } from './course-form/course-form.component'; import {
EmailValidator } from './course-form/email.validator';
@NgModule({ declarations: [
AppComponent, CourseFormComponent,
EmailValidator
],
imports: [ BrowserModule, FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
5. Add the following code in the course-form.component.html file for the email field as shown below
<div class="container">
<div [hidden]="submitted">
<h1>Course Form</h1>
LIMAT Page 70
MEAN STACK
<form (ngSubmit)="onSubmit()" TECHNOLOGIES LAB MANUAL
#courseForm="ngForm">
<div class="form-group">
<label for="id">Course Id</label>
<input type="text" class="form-control" required [(ngModel)]="course.courseId" name="id"
#id="ngModel">
<div [hidden]="id.valid || id.pristine" class="alert alert-danger"> Course Id is
required</div>
</div>
<div class="form-group">
<label for="name">Course Name</label>
<input type="text" class="form-control" required [(ngModel)]="course.courseName" minlength="4"
name="name" #name="ngModel">
<div *ngIf="name.errors && (name.dirty || name.touched)" class="alert alert- danger">
<div [hidden]="!name.errors.required">Name is required</div>
<div [hidden]="!name.errors.minlength">Name must be at least 4 characters long.</div>
</div>
</div>
<div class="form-group">
<label for="duration">Course Duration</label>
<input type="text" class="form-control" required [(ngModel)]="course.duration" name="duration"
#duration="ngModel">
<div [hidden]="duration.valid || duration.pristine" class="alert alert- danger">Duration
is required</div>
</div>
<div class="form-group">
<label for="email">Author Email</label>
<input type="text" class="form-control" required [(ngModel)]="course.email" name="email"
#email="ngModel" validateEmail>
<div *ngIf="email.errors && (email.dirty || email.touched)" class="alert alert- danger">
<div [hidden]="!email.errors.required">Email is required</div>
<div [hidden]="!email.errors.emailInvalid">{{email.errors.emailInvalid}}</div>
</div>
</div>
LIMAT Page 71
MEAN STACK TECHNOLOGIES LAB MANUAL
<button type="submit" class="btn btn-primary"
[disabled]="!courseForm.form.valid">Submit</button>
<button type="button" class="btn btn-link"
(click)="courseForm.reset()">Reset</button>
</form>
</div>
<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-3">Course ID</div>
<div class="col-9 pull-left">{{ course.courseId }}</div>
</div>
<div class="row">
<div class="col-3">Course Name</div>
<div class="col-9 pull-left">{{ course.courseName }}</div>
</div>
<div class="row">
<div class="col-3">Duration</div>
<div class="col-9 pull-left">{{ course.duration }}</div>
</div>
<div class="row">
<div class="col-3">Email</div>
<div class="col-9 pull-left">{{ course.email }}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>
</div>
6. Save the files and check the output in the browser
Output:
LIMAT Page 72
MEAN STACK TECHNOLOGIES LAB MANUAL
LIMAT Page 73
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-8(b)
LIMAT Page 74
}) MEAN STACK TECHNOLOGIES LAB MANUAL
LIMAT Page 75
.books li { cursor: pointer; MEAN STACK TECHNOLOGIES LAB MANUAL
position: relative; left: 0;
background-color: #eee; margin: 0.5em;
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;
LIMAT Page 76
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-8(c)
Module Name: RxJS Observables Create and use an observable in Angular. app.component.ts
import { Component } from '@angular/core'; import { Observable } from 'rxjs';
@Component({ selector: 'app-root',
styleUrls: ['./app.component.css'], templateUrl: './app.component.html'
})
export class AppComponent { data!: Observable<number>; myArray: number[] = []; errors!: boolean;
finished!: boolean; fetchData(): void {
this.data = new Observable(observer => { setTimeout(() => { observer.next(11); }, 1000), setTimeout(() => {
observer.next(22); }, 2000), setTimeout(() => { observer.complete(); }, 3000);
});this.data.subscribe((value) => this.myArray.push(value), error => this.errors = true,
() => this.finished = true);}
Line 2: imports Observable class from rxjs module
Line 11: data is of type Observable which holds numeric values Line 16: fetchData() is invoked on click of a
button
Line 17: A new Observable is created and stored in the variable data
Line 18-20: next() method of Observable sends the given data through the stream. With a delay of 1,2 and 3
seconds, a stream of numeric values will be sent. Complete() method completes the Observable stream i.e.,
closes the stream.
Line 22: Observable has another method called subscribe which listens to the data coming through the stream.
Subscribe() method has three parameters. The first parameter is a success callback which will be invoked upon
receiving successful data from the stream. The second parameter is an error callback which will be invoked
when Observable returns an error and the third parameter is a complete callback which will be invoked upon
successful streaming of values from Observable i.e., once complete() is invoked. After which the successful
response, the data is pushed to the local array called myArray, if any error occurs, a Boolean value called true
is stored in the errors variable and upon complete() will assign a Boolean value true in a finished variable.
app.component.html
<b> Using Observables!</b>
LIMAT Page 77
MEAN STACK TECHNOLOGIES LAB MANUAL
<h6 style="margin-bottom: 0">VALUES:</h6>
<div *ngFor="let value of myArray">{{ value }}</div>
<div style="margin-bottom: 0">ERRORS: {{ errors }}</div>
<div style="margin-bottom: 0">FINISHED: {{ finished }}</div>
<button style="margin-top: 2rem" (click)="fetchData()">Fetch Data</button>
Line 4: ngFor loop is iterated on myArray which will display the values on the page Line 6: {{ errors }} will
render the value of errors property if any
Line 8: Displays finished property value when complete() method of Observable is executed
Line 10: Button click event is bound with fetchData() method which is invoked and creates an observable with
a stream of numeric values
Output:
LIMAT Page 78
MEAN STACK TECHNOLOGIES LAB MANUAL
EXERCISE-9(a)
Module Name: Server Communication using HttpClient
Create an application for Server Communication using HttpClient
• In the example used for custom services concept, add HttpModule to the
app.module.ts to make use of HttpClient class.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import {HttpClientModule} from
'@angular/common/http'; import { AppComponent } from './app.component';
import { BookComponent } from './book/book.component';
@NgModule({
imports: [BrowserModule, HttpClientModule], declarations: [AppComponent, BookComponent], providers:
[],
bootstrap: [AppComponent]
})
export class AppModule { }
• Add the following code in book.service.ts file import { Injectable } from
'@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { Observable,
throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators'; import { Book } from './book';
@Injectable({ providedIn:'root'
})
export class BookService {
booksUrl = 'http://localhost:3020/bookList'; constructor(private http: HttpClient) { } getBooks():
Observable<Book[]> {
return this.http.get<Book[]>('http://localhost:3020/bookList').pipe( tap((data: any) => console.log('Data
Fetched:' + JSON.stringify(data))), catchError(this.handleError));
}
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(
LIMAT Page 79
MEAN STACK TECHNOLOGIES LAB MANUAL
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);
}
}
LIMAT Page 80
MEAN STACK TECHNOLOGIES LAB MANUAL
errorMessage!: string; ADD_BOOK!: boolean; UPDATE_BOOK!: boolean; DELETE_BOOK!: boolean;
constructor(private bookService: BookService) { } getBooks() { this.bookService.getBooks().subscribe({
next: books => this.books = books, error:error => this.errorMessage = <any>error
})
}
ngOnInit() { this.getBooks();
}
}
LIMAT Page 81
</li> MEAN STACK TECHNOLOGIES LAB MANUAL
</ul>
<button class="btn btn-primary" (click)="ADD_BOOK = true">Add Book</button>
<button class="btn btn-primary" (click)="UPDATE_BOOK =
true">Update Book</button>
<button class="btn btn-primary" (click)="DELETE_BOOK = true">Delete Book</button>
<br />
<div *ngIf="ADD_BOOK">
<table>
<tr>
<td>Enter Id of the book:</td>
<td>
<input type="number" #id />
<
</tr>
<br />
<tr>
<td>Enter Name of the Book:</td>
<td>
<input type="text" #name />
<br />
</td>
</tr>
<br />
<tr>
<td>
<button class="btn btn-primary" (click)="addBook(id.value, name.value); ADD_BOOK = false">
Add Record
</button>
</td>
</tr>
LIMAT Page 82
</table> MEAN STACK TECHNOLOGIES LAB MANUAL
<br />
</div>
<div *ngIf="UPDATE_BOOK">
<table>
<tr>
<td>Enter Id of the book:</td>
<td>
<input type="number" #id />
</td>
</tr>
<br />
<tr>
<td>Enter Name of the Book:</td>
<td>
<input type="text" #name />
<br />
</td>
</tr>
<br />
<tr>
<td>
<button class="btn-primary" (click)="updateBook(id.value, name.value); UPDATE_BOOK = false">
Update Record
</button>
</td>
</tr>
</table>
</div>
<br />
<div *ngIf="DELETE_BOOK">
<table>
<tr>
LIMAT Page 83
MEAN STACK TECHNOLOGIES LAB MANUAL
<td>Enter Id of the book:</td>
<td>
<i
</td>
</tr>
<br />
<tr>
<td>
<button class="btn btn-primary" (click)="deleteBook(id.value); DELETE_BOOK = false"> Delete Record
</button>
</td>
</tr>
</table>
</div>
<div class="error" *ngIf="errorMessage">{{ errorMessage }}</div>
•Save the files and check the output in the browser
Output:
Exercise-9(b)
LIMAT Page 84
MEAN STACK TECHNOLOGIES LAB MANUAL
Module Name: Communicating with different backend services using Angular HttpClient Create a custom
service called ProductService in which Http class is used to fetch data stored in the JSON files
Product-list.component.ts:
import { Component, OnInit } from '@angular/core'; import { ProductService } from
'./product.service'; @Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html', styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit { products: any[] = [];
constructor(private productService: ProductService) { } ngOnInit() {
this.productService.getProducts().subscribe((data) => {
this.products = data;
}); } }
Product.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' }) export class
ProductService {
private productsUrl = 'assets/products.json'; constructor(private http: HttpClient) { } getProducts():
Observable<any[]> {
return this.http.get<any[]>(this.productsUrl); } }
App.component.html:
<div *ngIf="products.length > 0; else noProducts">
<h2>Products</h2> <ul>
<li *ngFor="let product of products">
<h3>{{ product.name }}</h3>
<p>Price: {{ product.price }}</p>
<p>Description: {{ product.description }}</p>
</li> </ul> </div>
<ng-template #noProducts>
<p>No products available</p>
</ng-template>
LIMAT Page 85
App.component.ts: MEAN STACK TECHNOLOGIES LAB MANUAL
import { Component, OnInit } from '@angular/core';
import { ProductService } from './product-list/product.service';
@Component({ selector: 'my-app',
templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class
AppComponent implements OnInit { products: any[] = []; constructor(private
productService: ProductService) { } ngOnInit() {
this.productService.getProducts().subscribe((data) => { this.products = data;}); } }
App.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from
'@angular/common/http';
import { AppComponent } from './app.component'; @NgModule({ declarations:
[ AppComponent ],
imports: [ BrowserModule, HttpClientModul ], providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
LIMAT Page 86
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-10(a)
Module Name: Routing Basics, Router Links
Create multiple components and add routing to provide navigation between them
1. Consider the example used for the HttpClient concept.
2. Create another component with the name dashboard using the following
command D:\MyApp>ng generate component dashboard
3. Open dashboard.component.ts and add the following code 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[] = [];
costructor(
private router: Router,
private bookService: BookService) { } ngOnInit(): void { this.bookService.getBooks()
.subscribe({next:books => this.books = books.slice(1, 5)});
}gotoDetail(book: Book): void {this.router.navigate(['/detail', book.id]);}}
4. n dashboard.component.html and add the following code
<h3>Top Books</h3>
<div class="grid grid-pad">
<div *ngFor="let book of books" (click)="gotoDetail(book)" class="col-1-4">
LIMAT Page 87
float: left; MEAN STACK TECHNOLOGIES LAB MANUAL
}
*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;
}
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;
LIMAT Page 88
} MEAN STACK TECHNOLOGIES LAB MANUAL
@media (max-width: 600px) {
.module {
font-size: 10px; max-height: 75px;
}
}
@media (max-width: 1024px) {
.grid { margin: 0;
}
.module {
min-width: 60px;
}
}
6. Create another component called book-detail using the following command
D:\MyApp>ng generate component bookDetail
LIMAT Page 89
MEAN STACK TECHNOLOGIES LAB MANUAL
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);
}
}
7. 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-
LIMAT Page 90
MEAN STACK TECHNOLOGIES LAB MANUAL
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>
10. Open book-detail.component.css and add the following code label {
display: inline-block; width: 3em;
margin: 0.5em 0; color: #607d8b; font-weight: bold;
}
input { height: 2em;
font-size: 1em; padding-left: 0.4em;
}
utton {
margin-top: 20px; font-family: Arial;
LIMAT Page 91
background-color: #eee; MEAN STACK TECHNOLOGIES LAB MANUAL
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;
}
11. Generate PageNotFound component using the following CLI command
D:\MyApp>ng g c PageNotFound
12. Add below code to page-not-found.component.html:
<div>
<h1>404 Error</h1>
<h1>Page Not Found</h1>
</div>
13.Add the below code to app-routing.module.ts: import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { BookComponent } from
'./book/book.component';
import { DashboardComponent } from './dashboard/dashboard.component'; import { BookDetailComponent }
from './book-detail/book-detail.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; const appRoutes:
Routes = [
{ 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)
],
LIMAT Page 92
exports: [ RouterModule MEAN STACK TECHNOLOGIES LAB MANUAL
]
})
export class AppRoutingModule { }
14. Write the below-given code in app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from
'@angular/common/http'; import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { BookComponent } from './book/book.component';
import { DashboardComponent } from './dashboard/dashboard.component'; import { BookDetailComponent }
from './book-detail/book-detail.component'; import { AppRoutingModule } from './app-routing.module';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
@NgModule({
imports: [BrowserModule, HttpClientModule, FormsModule, AppRoutingModule],
declarations: [AppComponent, BookComponent, DashboardComponent, BookDetailComponent,
PageNotFoundComponent],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
15. Write the below-given code in app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
styleUrls: ['./app.component.css'], templateUrl: './app.component.html'
})
export class AppComponent { title = 'Tour of Books';
}
16.Write the below-given code in app.component.html
<h1>{{title}}</h1>
<nav>
LIMAT Page 93
MEAN STACK TECHNOLOGIES LAB MANUAL
<a [routerLink]='["/dashboard"]' routerLinkActive="active">Dashboard</a>
</nav>
<router-outlet></router-outlet>
17.Open app.component.css and add the following code 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;
}
button:disabled { background-color: #eee; color: #aaa;
cursor: auto;
LIMAT Page 94
MEAN STACK TECHNOLOGIES LAB MANUAL
18.Open book.component.html and update with below code.
<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> Save the files and check the output in the
browser.
Output:
LIMAT Page 95
MEAN STACK TECHNOLOGIES LAB MANUAL
Exercise-10(b)
@Component({
LIMAT Page 96
MEAN STACK TECHNOLOGIES LAB MANUAL
private loginService: LoginService, private router: Router,
private formbuilder: FormBuilder
){
ths.loginForm = this.formbuilder.group({ username: [],
password: [],
}password; this.loginService
.isUserAuthenticated(uname, pwd)
LIMAT Page 97
} MEAN STACK TECHNOLOGIES LAB MANUAL
isUserAuthenticated(username: string, password: string): Observable<boolean> { return
this.getAllUsers().pipe(
map(users => {
const Authenticateduser = users.find(user => (user.username === username) && (user.password
=== password));
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;}
6.Add the following code in app.module.ts:
LIMAT Page 98
'@angular/common/http'; MEAN STACK TECHNOLOGIES LAB MANUAL
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from
'./app.component';
import { BookComponent } from './book/book.component';
LIMAT Page 99
MEAN STACK TECHNOLOGIES LAB MANUAL
RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
1.Save the files and check the output in the browser.
Output:
Exercise-10(c)
Exercise-10(c)
Module Name: Nested Routes Implement Child Routes to a submodule.
1.Write the following code in app.module.ts. import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from
'@angular/common/http'; import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent
} from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { LoginComponent } from
'./login/login.component';
@NgModule({
imports: [BrowserModule, HttpClientModule, ReactiveFormsModule, AppRoutingModule], declarations:
[AppComponent, LoginComponent],
providers: [],
bootstrap: [AppComponent]
})
eport class AppModule { }
2.Write the following code in app-routing.module.ts. import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { LoginComponent } from
'./login/login.component';
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: '**', component: PageNotFoundComponent }
];
@NgModule({ imports: [
RouterModule.forRoot(appRoutes)
],
exports: [ RouterModule
]
})
Exercise-10(d)
Module Name: Nested Routes Implement Child Routes to a submodule.
1. Write the following code in app.module.ts. import { NgModule } from
'@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from
'@angular/common/http'; import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent
} from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { LoginComponent } from
'./login/login.component';
@NgModule({
imports: [BrowserModule, HttpClientModule, ReactiveFormsModule, AppRoutingModule], declarations:
[AppComponent, LoginComponent],
providers: [],
bootstrap: [AppComponent]
})
exprt class AppModule { }
2.Write the following code in app-routing.module.ts. import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { LoginComponent } from
'./login/login.component';
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: '**', component: PageNotFoundComponent }
];
7.Write the below code in book.component.ts: import { Component, OnInit } from '@angular/core'; import {
Router } from '@angular/router';
import { Book } from './book';
Exercise-12(a)
Module Name:Create and Delete Databases and Collections
Write MongoDB queries to Create and drop databases and collections.
To create a new database, you can use the use command in the MongoDB shell.However, note that a
database isn't actually created until you insert data into it.
// Switch to a new database (creates it if it doesn't exist)use newDatabaseName
1. Create a Collection:
Collections are created automatically when you insert data into them. However, youcan explicitly create a
collection using the createCollection() method.
// Create a new collection in the current
databasedb.createCollection("newCollectionName")
2. Drop a Collection:
To drop (delete) a collection, you can use the drop() method.
// Drop a collection db.collectionName.drop()
3. Drop a Database:
To drop a database, you can use the dropDatabase() method. Make sure to switchto the appropriate database
before using this command.// Drop the current database (make sure you're in the right
database)db.dropDatabase().