Meanstack Lab Manual AIML
Meanstack Lab Manual AIML
Mean stack stands for Mongo DB, Express JS, Angular, and Node JS. It is a set of these
technologies that are used to develop each end of a web application. Further details
about these technologies are given as follows:
Mongo DB : Its a database which is using BSON format to store data.
Express JS : Its a framework of JavaScript which enables developer to establish server.
Angular : Angular is client side framework which is used to develop User Interface.
Node JS :Node JS is a run time environment of JavaScript which allows developer to
execute JS code directly in console
Working of MEAN Stack:
Angular handles the implementation of the user interface (UI). Whenever the UI requires
data, it sends a request to the server, prompting the server to retrieve the necessary
information from MongoDB. Once the server successfully locates the required data, it
sends the response back to the client side.
Advantages of MEAN Stack:
Whole technologies requires only JavaScript to implement programs.
Improved re-usability of code.
Easy to learn.
OUTPUT:
Experiment 3: INTRODUCTION TO COMPONENTS
Angular components are the building blocks of a UI in an Angular application. These
components are associated with a template and are a subset of directives. The above
image shows the classification tree structure. A root component, the App Component,
branches out into other components, creating a hierarchy.
Creating a Component in Angular 10:
To create a component in any angular application, follow the below steps:
Get to the angular app via your terminal.
Create a component using the following command:
ng g c <component_name>
OR
ng generate component <component_name>
Using a component in Angular :
Go to the component.html file and write the necessary HTML code.
Go to the component.css file and write the necessary CSS code.
Write the corresponding code in component.ts file.
Run the Angular app using ng serve –open
OUTPUT
B)INTERPOLATION:
Interpolation is a way to transfer the data from a TypeScript code to an HTML template
(view), i.e. it is a method by which we can put an expression in between some text and
get the value of that expression. Interpolation basically binds the text with the
expression value
Syntax:
{{expression}}
STEP1: manu.component.html
Manu.component.ts
OUTPUT:
C)DIRECTIVES:
Directives are markers in the Document Object Model(DOM). Directives can be used
with any controller or HTML tag which will tell the compiler what exact operation or
behaviour is expected. There are some directives present that are predefined but if a
developer wants he can create new directives (custom-directive).
1. Component Directives
2. Attribute Directives(ngClass ,ngStyle ,ngModal)
3. Structural Directives(ngIf,ngSwitch,ngFor)
Ramakrishna.component.ts:
Ramakrishna.component.html:
Ramakrishna.component.css:
OUTPUT:
B)PIPES: The pipe() function in Angular is used to chain multiple operators together to
transform data. It receives an input value works on it and gives back a modified result.
You can recognize pipes in your template expressions by the pipe symbol ( | ).
1. Built-in Pipes
Angular comes equipped with built in pipes that handle a variety of common formatting
duties.
<p>Today's date: {{ today | date:'mediumDate' }}</p>
DatePipe-The DatePipe is utilized for date formatting. It enables us to present dates, in
styles like short, medium and full. For example we can utilize to exhibit the form of the
date.
{{ myDate | date: "short" }}
UpperCasePipe - This tool changes a text to capital letters. It requires a text, as input.
Gives back the text in all capital letters.
{{ myString | uppercase }}
LowerCasePipe - This particular pipe is utilized for changing a string to lowercase. Its
functionality resembles that of the UpperCasePipe except it changes the string to
lowercase instead.
{{ myString | lowercase }}
CurrencyPipe - This tool helps to convert numbers into currency values. You input a
number. It gives back a string showing the number, in the desired currency format.
{{ myNumber | currency: "USD" }}
EXPERIMENT 6: MORE ON COMPONENTS
Angular components are the building blocks of a UI in an Angular application. These
components are associated with a template and are a subset of directives.
Component Lifecycle
Angular components go through a series of stages, known as the component lifecycle. These
stages allow you to hook into specific moments when the component is created, updated, or
destroyed. The most commonly used lifecycle hooks are
ngOnChanges(): Called when input properties change. It's useful when the component
has @Input properties and you want to act on changes in those inputs.
ngOnInit(): Called once, right after the first ngOnChanges() call. This is ideal for
initialization logic, such as data fetching.
ngDoCheck(): Called during every change detection cycle. It allows you to manually check for changes, but
you should use it sparingly as it can lead to performance issues.
ngAfterViewInit(): Called after the component's view (and child views) have been initialized. It's useful for
actions that need access to the view, such as initializing 3rd-party libraries.
ngOnDestroy(): Called right before Angular destroys the component. This is a good place to clean up any
resources, like unsubscribing from observables or removing event listeners.
Output1:
parent works!
sendMessage() {
this.messageEmitter.emit('Hello from Child!'); // Emit the event
with data
}
Parent.component.ts:
receiveMessage(message: string) {
this.message = message; // Handle the event and data from the
child
}
Parent.component.html:
<app-child (messageEmitter)="receiveMessage($event)"></app-child>
<!-- Listen to the event -->
<p>{{ message }}</p> <!-- Display the received message -->
OUTPUT:
Send Message to Parent
Rama krishna Dept of AIML from Child!
EXPERIMENT 7 :
BUILDING NESTED COMPONENTS
In Angular, nested components refer to components that are used inside the templates of
other components. These nested components allow you to build a hierarchical structure of
components that can be easily reused and composed into larger, more complex UIs.
Concept of Nested Components
This concept follows the principle of component composition in Angular, which means you
can create a tree structure of components to form complex UIs. Each component is isolated in
terms of functionality and has its own template, making the application modular and easier to
maintain.
Isolation: Each component is isolated in terms of its logic and template. The
ChildComponent does not need to know about the parent, and the parent doesn't need
to know about the child.
In Angular, you can pass data from parent to child (or vice versa) using Input and Output
properties.
To send data from the parent component to the child component, we use the @Input()
decorator.
To send data from the child component to the parent component, we use the @Output()
decorator along with EventEmitter.
Output:
parent works!
Parent Component
Send Message to Parent
Experiment 8:
Angular provides two ways to handle forms: Template-driven forms and Reactive forms.
Both approaches help collect, validate, and manage user input, but they differ in how they are
structured and used. Here’s an overview of Angular forms and the two approaches:
Template-driven forms are simpler and more declarative. You define the form structure and
validation in the HTML template. Angular automatically handles the form creation and
validation.
Key Concepts:
NgForm Directive: This is automatically added to the form element, binding the form to
the Angular form model.
NgModel Directive: Used to bind form controls (like input elements) to model
properties.
Validation: You can use built-in directives like required, minlength, maxlength, and
pattern to perform validations.
Experiment 9:
Services and Dependency Injection:
1. Services in Angular
How DI works:
When you want to use a service in a component, you simply inject it into the component’s
constructor. Angular will take care of providing the instance of the service.
4. Providing Services
Root-level providers (provided in the root injector): This is the most common method,
especially when you need a singleton service across the entire application.
This is done using providedIn: 'root' in the @Injectable() decorator (as shown in
the DataService example).
Experiment:9
Services
Services are classes that provide reusable functionality and can be injected into other
components, directives, or services.
Dependency Injection (DI) is the mechanism Angular uses to inject instances of
services into components or other services automatically.
Steps:
Create a Service.
Inject the Service into a Component using Angular's DI system.
ng generate service auto
First we have to import Service in App.Component.ts
import { AutoService } from './auto.service';
OUTPUT:
Experiment 10.
Retrieving Data Using HTTP
Retrieving Data Using HTTP, Navigation, and Routing are fundamental parts of
creating dynamic and interactive web applications. These concepts are widely used in
frameworks like Angular, React, and Vue, but let’s focus on Angular for this
explanation
hen developing a web application, it’s common to need data from a backend server or an
external API. Angular provides a built-in service called HttpClient to make HTTP requests
like GET, POST, PUT, and DELETE.
Here’s how you can retrieve data from an API using Angular’s HttpClient:
a. Set Up HTTP Client
Import the HttpClientModule: First, ensure that the HttpClientModule is imported in
your Angular app module (app.module.ts).
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
imports: [HttpClientModule],
bootstrap: [AppComponent]
})
export class AppModule {}
Inject HttpClient: In the service or component where you want to fetch data, inject
HttpClient and use it to make HTTP requests.
b. Making a GET Request
Here’s an example of a simple service that fetches data from an API using a GET request.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
@Component({
selector: 'app-root',
template: `<ul><li *ngFor="let post of posts">{{ post.title }}</li></ul>`
})
export class AppComponent implements OnInit {
posts: any[] = [];
ngOnInit(): void {
// Subscribe to the observable to fetch data
this.dataService.getPosts().subscribe((data) => {
this.posts = data;
});
}
}
2. Navigation and Routing Basics
Angular provides Routing for navigation between different views in your application.
With routing, you can navigate between different components based on the URL.
a. Setting Up Routing
To use routing in Angular:
Import RouterModule: You need to configure the routes in the app-routing.module.ts.
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { PostComponent } from './post/post.component';
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
The HomeComponent will be displayed when the user navigates to the root (/).
The PostComponent will display when the user visits /post/:id, where id is a dynamic
parameter (e.g., /post/1).
Using RouterLink for Navigation: Use routerLink in your template to navigate
between components.
<!-- In a component template -->
<a routerLink="/post/1">Go to Post 1</a>
b. Using the ActivatedRoute to Retrieve Route Parameters
To retrieve the dynamic parameter (id) from the route, use ActivatedRoute in your
component.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-post',
template: `<h2>Post ID: {{ postId }}</h2>`
})
export class PostComponent implements OnInit {
postId: number;
ngOnInit(): void {
// Retrieve the route parameter using ActivatedRoute
this.route.paramMap.subscribe(params => {
this.postId = +params.get('id'); // Get 'id' as a number
});
}
}
c. Navigating Programmatically with Router
You can also navigate programmatically in your component using Angular’s Router.
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-home',
template: `<button (click)="goToPost()">Go to Post 1</button>`
})
export class HomeComponent {
goToPost() {
this.router.navigate(['/post', 1]); // Navigate to /post/1
}
}
3. Handling Navigation Events
You can listen to route changes and take action based on the navigation lifecycle using
Router.events.
import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
@Component({
selector: 'app-root',
template: `<h1>App</h1>`
})
export class AppComponent implements OnInit {
ngOnInit(): void {
// Subscribe to router events
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
console.log('Navigation started:', event.url);
}
});
}
}
EXPERIMENT 11:
NODEJS INTRODUCTION:
Node.js is a powerful, open-source, cross-platform JavaScript runtime that allows you to
execute JavaScript code on the server-side. It’s built on the V8 JavaScript engine (the
same engine that powers Google Chrome), and it enables developers to use JavaScript to
build fast, scalable network applications.
Key Concepts of Node.js
JavaScript on the Server: Traditionally, JavaScript was used in the browser for client-
side programming. With Node.js, JavaScript can now be run on the server, allowing
developers to use a single programming language (JavaScript) throughout both the
frontend and backend.
Asynchronous, Event-Driven: One of the key features of Node.js is its non-blocking
nature. It’s designed around an event-driven architecture, which means it uses an
event loop to handle requests asynchronously. Instead of waiting for one task to finish
before starting another (which is typical in traditional, blocking code), Node.js can handle
multiple requests at once without blocking, making it highly efficient.
Single Threaded: Node.js operates on a single thread, which means it doesn't require
multiple threads or processes to handle multiple client requests. This is achieved through
asynchronous I/O operations (like reading files or handling network requests) and an
event-driven model.
Built-in Libraries: Node.js comes with a rich set of libraries (also called modules) for
performing common tasks like handling HTTP requests, interacting with the file system,
working with streams, and more. These modules can be imported using require().
Why Use Node.js?
High Performance: Node.js is known for its fast performance because it uses the V8
engine, which compiles JavaScript to native machine code.
Scalability: Since it uses non-blocking I/O operations, Node.js can handle thousands of
concurrent connections with minimal overhead.
Real-Time Applications: Node.js is well-suited for applications that require real-time
interaction, such as chat applications, online gaming, live updates, or anything that
requires handling many concurrent requests with low latency.
Unified Language: By using JavaScript for both the client and server-side code,
developers can write full-stack applications using a single language, which simplifies the
development process and reduces the context switching between languages.
NPM (Node Package Manager): Node.js has an extensive package ecosystem called
NPM. It allows developers to easily install, share, and manage libraries and tools for
Node.js applications. There are thousands of open-source packages available through
NPM to simplify development.
Basic Example of a Node.js Application
Create a file server.js:
const http = require('http'); // Import the built-in HTTP module
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
Run the server:
node app.js
Access the server:
Visit http://localhost:3000 in your browser, and you should see Hello, Express!
Common Use Cases for Node.js
Real-Time Applications: Chat apps, live updates, collaborative tools (like Google Docs).
API Servers: Build RESTful APIs or GraphQL APIs.
Single Page Applications (SPAs): Serve dynamic web applications that interact with a
backend.
Microservices: Node.js is lightweight and works well for building scalable microservices
architectures.
Web Servers: Handle HTTP requests and serve web pages, using frameworks like
Express.
EXPERIMENT 12:
Exploring Language additions to the v8 javascript engine
The V8 JavaScript engine is continuously evolving, and with it, JavaScript itself is being
updated with new features and capabilities. V8 is the engine used by Google Chrome and
Node.js, and its updates often introduce new language features, optimizations, and tools
to make JavaScript faster and more powerful.
Here are some recent and upcoming language additions and features that have been
added to JavaScript via V8:
1. Top-level Await (ECMAScript 2022)
What it is: This feature allows you to use await at the top level of a module, without
needing to wrap it in an async function. Prior to this, await could only be used within
async functions, but now you can directly use it at the module level.
Why it's useful: Makes asynchronous programming in modules simpler and cleaner.
// With Top-level await
const data = await fetchData();
console.log(data);
Supported in V8: Introduced in V8 10.2 (Node.js 16.x).
Logical Assignment Operators (ECMAScript 2021)
What it is: JavaScript added three new logical assignment operators: &&=, ||=, and ??=.
These operators combine logical operations with assignment.
Why it's useful: Simplifies common patterns where you check a value before
assignment.
let a = null;
a ||= 'default'; // equivalent to if (!a) a = 'default';
console.log(a); // 'default'
WeakRefs (ECMAScript 2021)
What it is: WeakRefs allow you to hold a weak reference to an object. This means that
the garbage collector can collect the object even if it has a reference in a WeakRef.
Why it's useful: Useful for cases where you want to hold references to objects, but
don't want those references to prevent garbage collection (like in caching or lifecycle
management).
let obj = { name: 'Weak Reference' };
const weakRef = new WeakRef(obj);
OUTPUT:
Experiment 15:
1. Buffers (Handling Binary Data)
Buffers are used to handle raw binary data directly in memory, making them useful for
working with files, network sockets, and streams.
Buffers store binary data and can be converted to a string using .toString().
Types of Streams
npm init –y