Mean Stack Technologies 2 Lab Manual
Mean Stack Technologies 2 Lab Manual
Mean Stack Technologies 2 Lab Manual
EXERCISE-1(a)
REQUIREMENTS DETAILS
You can use the Angular CLI to create projects, generate application and library code, and
perform a variety of ongoing development tasks such as testing, bundling, and deployment.
To install the Angular CLI, open a terminal window and run the following command:
Carefully read the message displayed after executing the command and follow the
instructions. Make sure you understand the implications of setting an execution policy.
1. Run the CLI command ng new and provide the name my-app, as shown here:
2. The ng new command prompts you for information about features to include in the
initial app. Accept the defaults by pressing the Enter or Return key.
The Angular CLI installs the necessary Angular npm packages and other dependencies.
This can take a few minutes.
The CLI creates a new workspace and a simple Welcome app, ready to run.
The Angular CLI includes a server, for you to build and serve your app locally.
my-app
ng serve --open
The ng serve command launches the server, watches your files, and rebuilds the app as you
make changes to those files.
The --open (or just -o) option automatically opens your browser to http://localhost:4200/.
Output:
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/.
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 share pseudonymous usage data about this project with the Angular
Team
Thank you for sharing pseudonymous usage data. Should you change your mind, the
following
ng analytics disable
√ Compiled successfully.
Exercise-1(b)
Module Name: Components and Modules Create a new component called hello and render
Hello Angular on the page.
Process :
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.
npm install
ng serve
In this step, you get to know the files that make up a default Angular app.
In this app, the styles are in a separate file while the component's code
and HTML template are in this file.
After you have reviewed the files that make up an Angular app project, continue to the next
step.
In this step, you update the Angular project files to change the displayed content.
In your IDE:
1. Open first-app/src/index.html.
2. In index.html, replace the <title> element with this code to update the title of the app.
Replace in src/index.html
<title>Homes</title>
Replace in src/app/app.component.ts
5. In app.component.ts, in the AppComponent class definition, replace the title line with
this code to change the component title.
Replace in src/app/app.component.ts
title = 'homes';
6. If you stopped the ng serve command from step 1, in the Terminal window of your IDE,
run ng serve again.
7. Open your browser and navigate to localhost:4200 and confirm that the app builds
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="/">
<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:
bootstrapApplication(AppComponent,
{providers: [provideProtractorTestingSupport()]})
Style.css:
10
margin: 0;
padding: 0;
body {
:root {
--primary-color: #605DC8;
--secondary-color: #8B89E6;
--accent-color: #e8e7fa;
--shadow-color: #E8E8E8;
button.primary {
padding: 10px;
background: var(--primary-color);
color: white;
border-radius: 8px;
11
App.component.css
:host {
--content-padding: 10px;
header {
display: block;
height: 60px;
padding: var(--content-padding);
.content {
padding: var(--content-padding);
App.component.ts
@Component({
selector: 'app-root',
standalone: true,
imports: [],
template: `<h1>Hello</h1>`,
styleUrls: ['./app.component.css'],
})
12
title = 'default';}
Output:
~/projects/qqsjdl--run
npm WARN deprecated [email protected]: 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.
> ng serve
13
✔ Compiled successfully.
5 unchanged chunks
✔ Compiled successfully.
14
15
Exercise-1(c)
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:
@Component({
selector: 'app-hello',
templateUrl: "./hello.component.html",
styleUrls: ['./hello.component.css']
})
courseName = "MSD";
constructor() { }
ngOnInit() {
changeName() {
this.courseName = "CSE";
hello.component.html:
<h1>Welcome</h1>
16
hello.component.css:
p{
font-size:20px;
Output:
17
√ Compiled successfully.
18
Exercise-2(a)
• 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?
Types of Directives
Components
Structural Directives
• A Structural directive changes the DOM layout by adding and removing DOM
elements.
Syntax: *directive-name=expression
ngIf: ngIf directive renders components or elements conditionally based on whether or not
an expression is true or false.
19
Syntax:
1. *ngIf = "expression"
Open already created app and do the required modifications in app.component.ts file
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
isAuthenticated!: boolean;
submitted = false;
userName!: string;
this.submitted = true;
this.userName = name;
this.isAuthenticated = true;
} else {
this.isAuthenticated = false;
20
app.component.html
<div *ngIf="!submitted">
<form>
<label>User Name</label>
<label for="password">Password</label>
</form>
</div>
<div *ngIf="submitted">
</div>
<ng-template #failureMsg>
</ng-template>
</div>
app.module.ts
@NgModule({
21
declarations: [AppComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent],
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyApp</title>
<base href="/">
</head>
<body>
<app-root></app-root>
</body>
</html>
22
Output:
If the usename and password are correct console will display this output.
If the username and password are incorrect Invalid Login !! will be displayed.
23
Exercise-2(b)
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
courses: any[] = [
];
<ul>
{{ i }} - {{ course.name }}
</li>
</ul>
24
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
courses: any[] = [
];
Output:
25
Exercise-2(c)
App.componet.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
c=0;
nextChoice(){
this.c++;
if(this.c>6){
this.c=0;} }}
App.component.html
<div [ngSwitch]="c">
<p *ngSwitchCase="1">HTML</p>
<p *ngSwitchCase="2">CSS</p>
<p *ngSwitchCase="3">Javascript</p>
<p *ngSwitchCase="4">Typescript</p>
26
<p *ngSwitchCase="5">Angular</p>
<p *ngSwitchCase="6">Exit</p>
</div>
<div>
</div>
Output:
In the above output, the current choice is incremented up to 6 and then it is reset to 0
27
Exercise-2(d)
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
@NgModule({
declarations: [
AppComponent,
RepeatDirective
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
28
repeat.directive.ts
import { Directive ,TemplateRef,ViewContainerRef,Input} from '@angular/core';
@Directive({
selector: '[appRepeat]'
})
for(let i=0;i<count;i++){
this.viewContainer.createEmbeddedView(this.templatRref);
App.component.html
</ng-template>
29
Output:
30
Exercise-3(a)
• 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.
app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
colorName = 'blue';
fontWeight = 'bold';
31
app.component.html
<p
[ngStyle]="{
color: colorName,
'font-weight': fontWeight,
borderBottom: borderStyle
}"
>
</p>
Save the changes to files and check the browser for output.
Output:
32
Exercise-3(b)
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.
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
isBordered = true;}
Here we created a Boolean expression isBordered to evaluate the border style for html
pag
</div>
33
.bordered {
background-color: #eee;
You can
Output:
34
Exercise-3(c)
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.
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:
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:
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
35
@NgModule({
declarations: [
AppComponent,
MessageDirective
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
@Directive({
selector: '[appMessage]',
})
36
@HostListener('click') onClick() {
this.el.nativeElement.innerHTML = this.message;
<h3>Attribute Directive</h3>
h3 {
color: #369;
font-size: 250%;
p{
color: #ff0080;
font-size: 150%;
@Component({
37
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
Output:
38
Exercise-4(a)
Module Name: Property Binding .(Binding image with class property using property binding.)
<img [src]='imgUrl'>
39
Exercise-4(b)
Binding colspan attribute of a table element to the class property to display the following output
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
colspanValue = '2';
}
<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>
OUTPUT:-
40
Exercise-4(c)
Binding an element using inline style and user actions like entering text in input fields.
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
41
Output:
42
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
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'product details';
productCode = 'PROD_P001';
productName = 'Laptop';
}
</table>
3. Save the files and check the output in the browser
OUTPUT:-
43
Exercise-5(b)
Applying 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.
@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.
44
<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>
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
OUTPUT:-
45
Exercise-5(c)
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
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
@NgModule({
declarations: [
AppComponent,
CoursesListComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
46
<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>
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
show!: boolean; }
47
OUTPUT:-
48
Exercise-6(a)
Steps:
1. Open the courses-list.component.ts file created in the example of nested components and
add the following code
49
<th>Course Name</th>
</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>
@Component({
selector: 'app-root',
styleUrls: ['./app.component.css'],
templateUrl: './app.component.html'
})
name!: string;
50
Output:
51
Exercise-6(b)
Steps:
1. Open the courses-list.component.ts file created in the previous example and add the
following code
@Component({
selector: 'app-courses-list',
templateUrl: './courses-list.component.html',
styleUrls: ['./courses-list.component.css']
})
courses = [
];
register(courseName: string) {
this.registerEvent.emit(courseName);
}}
52
<table border="1">
<thead>
<tr>
<th>Course ID</th>
<th>Course Name</th>
<th></th>
</tr>
</thead>
<tbody>
<td><button (click)="register(course.courseName)">Register</button></td>
</tr>
</tbody>
</table>
<h2>Courses List</h2>
<app-courses-list (registerEvent)="courseReg($event)"></app-courses-list>
53
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
message!: string;
courseReg(courseName: string) {
Output:
54
Exercise-6(c)
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. .cmp {
2. padding: 6px;
55
3. margin: 6px;
4. border: blue 2px solid;
5. }
1. .cmp {
2. border: green 2px solid;
3. padding: 6px;
4. margin: 6px;
5. }
9. }
56
1. .cmp {
2. padding: 8px;
3. margin: 6px;
4. border: 2px solid red;
5. }
6. </div>
10. Save the files and check the output in the browser
Output:
ViewEncapsulation.None
57
Output:
58
Exercise-6(d)
Steps:
1. import {
2. Component, OnInit, DoCheck, AfterContentInit, AfterContentChecked,
3. AfterViewInit, AfterViewChecked,
4. OnDestroy
5. } from '@angular/core';
6. @Component({
7. selector: 'app-root',
8. styleUrls: ['./app.component.css'],
9. templateUrl: './app.component.html'
10. })
11. export class AppComponent implements OnInit, DoCheck,
12. AfterContentInit, AfterContentChecked,
13. AfterViewInit, AfterViewChecked,
14. OnDestroy {
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. }
59
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.
12. }
1. <h2>Child Component</h2>
2. <h2>{{title}}</h2>
60
Output:
61
Exercise-7(a)
Steps:
1. Create course.ts file under the course-form folder and add the following code
12. }
3. Install bootstrap
1. ...
2. "styles": [
3. "styles.css",
62
4. "./node_modules/bootstrap/dist/css/bootstrap.min.css"
5. ],
6. ...
1. <div class="container">
2. <div [hidden]="submitted">
3. <h1>Course Form</h1>
4. <form (ngSubmit)="onSubmit()" #courseForm="ngForm">
5. <div class="form-group">
6. <label for="id">Course Id</label>
7. <input type="text" class="form-control" required [(ngModel)]="course.courseId"
name="id" #id="ngModel">
8. <div [hidden]="id.valid || id.pristine" class="alert alert-danger">
9. Course Id is required
10. </div>
11. </div>
12. <div class="form-group">
13. <label for="name">Course Name</label>
14. <input type="text" class="form-control" required
[(ngModel)]="course.courseName" name="name" #name="ngModel">
15. <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
16. Course Name is required
17. </div>
18. </div>
19. <div class="form-group">
20. <label for="duration">Course Duration</label>
21. <input type="text" class="form-control" required [(ngModel)]="course.duration"
name="duration" #duration="ngModel">
22. <div [hidden]="duration.valid || duration.pristine" class="alert alert-danger">
23. Duration is required
24. </div>
25. </div>
26. <button type="submit" class="btn btn-default"
[disabled]="!courseForm.form.valid">Submit</button>
27. <button type="button" class="btn btn-default" (click)="courseForm.reset()">New
Course</button>
28. </form>
29. </div>
30. <div [hidden]="!submitted">
31. <h2>You submitted the following:</h2>
32. <div class="row">
33. <div class="col-xs-3">Course ID</div>
34. <div class="col-xs-9 pull-left">{{ course.courseId }}</div>
35. </div>
63
47. </div>
1. input.ng-valid[required] {
2. border-left: 5px solid #42A948; /* green */
3. }
4. input.ng-dirty.ng-invalid:not(form) {
5. border-left: 5px solid #a94442; /* red */
6. }
1. <app-course-form></app-course-form>
64
Output:
65
Exercise-7(b)
Steps:
66
1. <div class="container">
2. <h1>Registration Form</h1>
3. <form [formGroup]="registerForm">
4. <div class="form-group">
5. <label>First Name</label>
6. <input type="text" class="form-control" formControlName="firstName">
7. <div *ngIf="registerForm.controls['firstName'].errors" class="alert alert-
danger">
8. Firstname field is invalid.
9. <p *ngIf="registerForm.controls['firstName'].errors?.['required']">
10. This field is required!
11. </p>
12. </div>
13. </div>
67
1. .ng-valid[required] {
2. border-left: 5px solid #42A948; /* green */
3. }
4. .ng-invalid:not(form) {
5. border-left: 5px solid #a94442; /* red */
6. }
68
1. <app-registration-form></app-registration-form>
Output:
69
Exercise-7(c)
Create a custom validator for an email field in the employee registration form
( reactive form)
Steps:
70
36. }
2. Add HTML controls for the email field in the registration-form.component.html file
as shown below
1. <div class="container">
2. <h1>Registration Form</h1>
3. <form [formGroup]="registerForm">
4. <div class="form-group">
5. <label>First Name</label>
6. <input type="text" class="form-control" formControlName="firstName">
7. <div *ngIf="registerForm.controls['firstName'].errors" class="alert alert-
danger">
8. Firstname field is invalid.
9. <p *ngIf="registerForm.controls['firstName'].errors?.['required']">
10. This field is required!
11. </p>
12. </div>
13. </div>
14. <div class="form-group">
15. <label>Last Name</label>
16. <input type="text" class="form-control" formControlName="lastName">
17. <div *ngIf="registerForm.controls['lastName'].errors" class="alert alert-danger">
18. Lastname field is invalid.
19. <p *ngIf="registerForm.controls['lastName'].errors?.['required']">
20. This field is required!
21. </p>
22. </div>
23. </div>
24. <div class="form-group">
25. <fieldset formGroupName="address">
26. <legend>Address:</legend>
27. <label>Street</label>
28. <input type="text" class="form-control" formControlName="street">
29. <label>Zip</label>
30. <input type="text" class="form-control" formControlName="zip">
31. <label>City</label>
32. <input type="text" class="form-control" formControlName="city">
33. </fieldset>
34. </div>
71
72
Exercise-8(a)
Create a custom validator for the email field in the course registration form.
@Component({
selector: 'app-course-form',
templateUrl: './course-form.component.html',
styleUrls: ['./course-form.component.css']
})
export class CourseFormComponent {
}
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 },
],
})
export class EmailValidator implements Validator {
validate(control: FormControl): any {
const emailRegexp =
73
/^([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
@NgModule({
declarations: [
AppComponent,
CourseFormComponent,
EmailValidator
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
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>
<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>
74
<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 [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>
75
</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:
76
Exercise-8(b)
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.
3. Create a file with the name book.ts under the book folder and add the following code.
id!: number;
name!: string;
3. Create a file with the name books-data.ts under the book folder and add the following code.
77
];
4. Create a service called BookService under the book folder using the following CLI command
@Injectable({
providedIn: 'root'
})
getBooks() {
return BOOKS;
}}
78
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
books!: Book[];
getBooks() {
this.books = this.bookService.getBooks();
ngOnInit() {
this.getBooks();
}}
<h2>My Books</h2>
<ul class="books">
</li></ul>
8. Add the following code in book.component.css which has styles for books
.books {
margin: 0 0 2em 0;
list-style-type: none;
79
padding: 0;
width: 13em;
.books li {
cursor: pointer;
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;
background-color: #607d8b;
line-height: 0.5em;
position: relative;
80
left: -1px;
top: -4px;
height: 1.8em;
margin-right: 0.8em;
<app-book></app-book>
10. Save the files and check the output in the browser
Output:
81
Exercise-8(c)
app.component.ts
@Component({
selector: 'app-root',
styleUrls: ['./app.component.css'],
templateUrl: './app.component.html'
})
data!: Observable<number>;
errors!: boolean;
finished!: boolean;
fetchData(): void {
82
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
Line 4: ngFor loop is iterated on myArray which will display the values on the page
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
83
Output:
84
EXERCISE-9(a)
• In the example used for custom services concept, add HttpModule to the app.module.ts to
make use of HttpClient class.
@NgModule({
providers: [],
bootstrap: [AppComponent]
})
@Injectable({
providedIn:'root'
})
85
booksUrl = 'http://localhost:3020/bookList';
getBooks(): Observable<Book[]> {
return this.http.get<Book[]>('http://localhost:3020/bookList').pipe(
catchError(this.handleError));
catchError(this.handleError));
catchError(this.handleError)
);
return this.http.delete(url).pipe(
catchError(this.handleError));
86
errMsg = err.error.message;
} else {
errMsg = err.error.status;
return throwError(()=>errMsg);
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
books!: Book[];
87
errorMessage!: string;
ADD_BOOK!: boolean;
UPDATE_BOOK!: boolean;
DELETE_BOOK!: boolean;
getBooks() {
this.bookService.getBooks().subscribe({
})
let id=parseInt(bookId)
this.bookService.addBook({id, name })
let id=parseInt(bookId)
let id=parseInt(bookId)
this.bookService.deleteBook(id)
88
ngOnInit() {
this.getBooks();
<h2>My Books</h2>
<ul class="books">
</li>
</ul>
<br />
<div *ngIf="ADD_BOOK">
<table>
<tr>
<td>
</td>
</tr>
89
<br />
<tr>
<td>
<br />
</td>
</tr>
<br />
<tr>
<td>
Add Record
</button>
</td>
</tr>
</table>
<br />
</div>
<div *ngIf="UPDATE_BOOK">
<table>
<tr>
<td>
90
</td>
</tr>
<br />
<tr>
<td>
<br />
</td>
</tr>
<br />
<tr>
<td>
Update Record
</button>
</td>
</tr>
</table>
</div>
<br />
<div *ngIf="DELETE_BOOK">
91
<table>
<tr>
<td>
</td>
</tr>
<br />
<tr>
<td>
Delete Record
</button>
</td>
</tr>
</table>
</div>
92
Output:
93
Exercise-9(b)
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:
selector: 'app-product-list',
})
this.products = data;
}); } }
Product.service.ts:
getProducts(): Observable<any[]> {
return this.http.get<any[]>(this.productsUrl); } }
App.component.html:
<h2>Products</h2> <ul>
94
<ng-template #noProducts>
</ng-template>
App.component.ts:
App.module.ts:
declarations: [ AppComponent ],
providers: [],
bootstrap: [AppComponent]
})
95
Exercise-10(a)
Create multiple components and add routing to provide navigation between them
2. Create another component with the name dashboard using the following command
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
constructor(
ngOnInit(): void {
this.bookService.getBooks()
96
<h3>Top Books</h3>
</div>
</div>
</div>
[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;
97
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;
98
color: #607d8b;
.grid-pad {
padding: 10px 0;
padding-right: 20px;
.module {
font-size: 10px;
max-height: 75px;
.grid {
margin: 0;
.module {
min-width: 60px;
99
7. Open book.service.ts and add getbook() method as shown below to fetch specific book details
@Injectable({
providedIn:'root'
})
booksUrl = 'http://localhost:3020/bookList';
getBooks(): Observable<Book[]> {
catchError(this.handleError));
getBook(id: any) {
return this.getBooks().pipe(
);
100
catchError(this.handleError));
catchError(this.handleError)
);
return this.http.delete(url).pipe(
catchError(this.handleError));
errMsg = err.error.message;
} else {
101
errMsg = err.error.status;
return throwError(()=>errMsg);
@Component({
selector: 'app-book-detail',
templateUrl: './book-detail.component.html',
styleUrls: ['./book-detail.component.css'],
})
book!: Book;
error!: any;
constructor(
){}
ngOnInit() {
this.route.paramsMap.subscribe(params => {
this.bookService.getBook(params.get('id')).subscribe((book) => {
102
});
});
goBack() {
window.history.back();
}}
<div *ngIf="book">
<div>
</div>
<button (click)="goBack()">Back</button>
</div>
label {
display: inline-block;
width: 3em;
margin: 0.5em 0;
color: #607d8b;
font-weight: bold;
103
input {
height: 2em;
font-size: 1em;
padding-left: 0.4em;
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
border-radius: 4px;
cursor: pointer;
cursor: hand;
button:hover {
background-color: #cfd8dc;
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
D:\MyApp>ng g c PageNotFound
104
<div>
<h1>404 Error</h1>
</div>
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
})
105
@NgModule({
providers: [],
bootstrap: [AppComponent]
})
@Component({
106
selector: 'app-root',
styleUrls: ['./app.component.css'],
templateUrl: './app.component.html'
})
<h1>{{title}}</h1>
<nav>
</nav>
<router-outlet></router-outlet>
h1 {
color: #369;
font-size: 250%;
h2, h3 {
color: #444;
font-weight: lighter;
body {
107
margin: 2em;
color: #888;
a{
cursor: pointer;
cursor: hand;
button {
font-family: Arial;
background-color: #eee;
border: none;
border-radius: 4px;
cursor: pointer;
cursor: hand;
button:hover {
background-color: #cfd8dc;
button:disabled {
background-color: #eee;
color: #aaa;
cursor: auto;
108
39.
nav a {
text-decoration: none;
margin-right: 10px;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
color: #607D8B;
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
nav a.active {
color: #039be5;
*{
109
18. Open styles.css under the src folder and add the following code
body{
padding:10px;
19.Open book.component.ts file in book folder and add the following code
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
10.
books!: Book[];
errorMessage!: string;
getBooks() {
this.bookService.getBooks().subscribe({
})
ngOnInit(): void {
this.getBooks()}}
110
<h2>My Books</h2>
<ul class="books">
</li>
</ul>
Output:
111
Exercise-10(b)
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 URL of Bookscomponent in another tab or window, or if the user tries
{{ invalidCredentialMsg }}
</div>
<br />
<p>
Password
<input
type="password"
formControlName="password"
/>
</p>
<p><button type="submit">Submit</button></p>
</form>
</div>
112
@Component({
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
invalidCredentialMsg!: string;
loginForm!: FormGroup;
constructor(
){
this.loginForm = this.formbuilder.group({
username: [],
password: [],
});
onFormSubmit(): void {
this.loginService
113
.isUserAuthenticated(uname, pwd)
.subscribe({next:(authenticated) => {
if (authenticated) {
this.router.navigate(['/books']);
} else {
}});
3. Create user.ts file under login folder and add the following code to user.ts file:
4. Add the following code to the login.service.ts file inside login folder:
const USERS = [
];
@Injectable({
providedIn: 'root'
114
})
getAllUsers(): Observable<User[]> {
return usersObservable;
return this.getAllUsers().pipe(
map(users => {
if (Authenticateduser) {
this.isloggedIn = true;
} else {
this.isloggedIn = false;
return this.isloggedIn;
})
);
isUserLoggedIn(): boolean {
return this.isloggedIn;
115
5. Create another service class called login-guard.service inside login folder and add the following
code:
@Injectable({
providedIn: 'root'
})
canActivate(): boolean {
if (this.loginService.isUserLoggedIn()) {
return true;}
this.router.navigate(['/login']);
return false;}
116
@NgModule({
providers: [],
bootstrap: [AppComponent]})
{path: 'login',component:LoginComponent},
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)],
117
exports: [RouterModule]
})
Output:
118
Exercise-10(c)
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.
1. Write the code given below in the book-routing.module.ts file inside book folder.
path: '',
component: BookComponent,
canActivate: [LoginGuardService]
];
@NgModule({
imports: [RouterModule.forChild(bookRoutes)],
exports: [RouterModule]
})
2. Create the book.module.ts file inside book folder and add the following code
119
@NgModule({
declarations: [BookComponent]
})
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
120
exports: [
RouterModule
})
@NgModule({
providers: [],
bootstrap: [AppComponent]
})
121
Output:
If lazy loading is added to the demo, it has loaded in 900 ms. As BookComponent will be loaded after
login, the load time is reduced initially.
122
Exercise-10(d)
@NgModule({
providers: [],
bootstrap: [AppComponent]
})
123
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
})
<h1>{{title}}</h1>
<nav>
</nav>
<router-outlet></router-outlet>
124
@NgModule({
})
path: '',
component: BookComponent,
children: [
],
canActivate: [LoginGuardService]
}];
@NgModule({
imports: [RouterModule.forChild(bookRoutes)],
125
exports: [RouterModule]
})
<br/>
<h2>MyBooks</h2>
<ul class="books">
</li>
</ul>
<div>
<router-outlet></router-outlet>
</div>
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
126
books: Book[]=[];
errorMessage!: string;
getBooks() {
this.bookService.getBooks().subscribe({
})
this.router.navigate(['/books/detail/', book.id]);
ngOnInit(): void {
this.getBooks();
<div *ngIf="book">
<div>
</div>
<button (click)="goBack()">Back</button>
</div>
127
@Component({
selector: 'app-book-detail',
templateUrl: './book-detail.component.html',
styleUrls: ['./book-detail.component.css'],
})
book!: Book;
error!: any;
constructor(
){}
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.bookService.getBook(params.get('id')).subscribe((book) => {
});
});
goBack() {
window.history.back();
128
<h3>Top Books</h3>
</div>
</div>
</div>
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
constructor(
ngOnInit(): void {
129
this.bookService.getBooks()
this.router.navigate(['/books/detail', book.id]);
130
Exercise-11(a)
▪ Start MongoDB:
• Windows: MongoDB is typically installed as a service and
startsautomatically. You can also manually start it using the Services
application.
• macOS and Linux: Start MongoDB using the terminal by running
● mongod.
131
1.Create a Cluster:
● After signing up and logging in, click the "Build a New Cluster"button.
● Choose a cloud provider, region, and cluster settings. You can
choosethe free tier (M0) to get started.
2. Configure Security:
● Click "Security" in the left-hand menu.
● Add your IP address to the IP Whitelist to allow connections to yourcluster.
3. Connect to Your Cluster:
● Click "Clusters" in the left-hand menu.
● Click the "Connect" button for your cluster.
● Choose "Connect Your Application" to get the connection string.
4. Connect to Atlas Cluster using MongoDB Shell:
● Open a terminal window.
● Run mongo "your_connection_string" to connect to your Atlascluster. Replace
132
Exercise-11(b)
SOURCE CODE:
To insert documents into a collection, you can use the insertOne() or insertMany()
methods.
])
$lt: 40 } })
133
3. Update Documents:
To update documents in a collection, you can use the updateOne() or
updateMany()
methods.
db.collectionName.upda
teOne(
{ field: value },
{ field: value },
134
Exercise-12(a)
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.
1. Create a Collection:
Collections are created automatically when you insert data into them.
However, youcan explicitly create a collection using the createCollection()
method.
2. Drop a Collection:
To drop (delete) a collection, you can use the drop() method.
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().
135
Exercise-12(b)
Write MongoDB queries to work with records using find(), limit(), sort(),
createIndex(), aggregate()..
SOURCE CODE:
find(): The find() method retrieves documents from a collection that
match aspecified query. You can use various query operators to filter
the results.
$lt: 40 } })\
limit(): The limit() method restricts the number of documents returned by a query.
sort(): The sort() method arranges the documents in a specific order based on oneor
more fields.
136
// Create an
ascending index on
a field
db.collectionName.
createIndex({ field:
1 })
// Create a
descending index on
a field
db.collectionName.
createIndex({ field: -
1 })