KEMBAR78
Full Stack Material | PDF | Java Script | Web Development
0% found this document useful (0 votes)
22 views56 pages

Full Stack Material

The document outlines the syllabus for a Full Stack Development course (MERN) offered by the Department of CSE, covering essential topics such as Node.js, MongoDB, Express, React, and Angular. It includes detailed explanations of web development frameworks, core concepts in front-end and back-end development, and the importance of JavaScript fundamentals. Additionally, it provides installation instructions for Node.js and highlights the significance of various full-stack components and technologies.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views56 pages

Full Stack Material

The document outlines the syllabus for a Full Stack Development course (MERN) offered by the Department of CSE, covering essential topics such as Node.js, MongoDB, Express, React, and Angular. It includes detailed explanations of web development frameworks, core concepts in front-end and back-end development, and the importance of JavaScript fundamentals. Additionally, it provides installation instructions for Node.js and highlights the significance of various full-stack components and technologies.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

Full Stack Development (MERN)-CS631PE Department of CSE

Full Stack Development


JNTUH

T D SAI KISHORE
Assistant Professor
Department
of
Mechanical Engineering

1
Full Stack Development (MERN)-CS631PE Department of CSE

Syllabus
UNIT-I Introduction to Full Stack Development: Understanding the Basic Web Development
Framework- User, Browser, Webserver, Backend Services, Full Stack Components - Node.js, MongoDB,
Express, React, Angular. Java Script Fundamentals, NodeJS- Understanding Node.js, Installing Node.js,
Working with Node Packages, creating a Node.js Application, Understanding the Node.js Event Model,
Adding Work to the Event Queue, Implementing Callbacks.
UNIT-II Node.js:
Working with JSON, Using the Buffer Module to Buffer Data, Using the Stream Module to Stream Data,
Accessing the File System from Node.js- Opening, Closing, Writing, Reading Files and other File System
Tasks. Implementing HTTP Services in Node.js- Processing URLs, Processing Query Strings and Form
Parameters, Understanding Request, Response, and Server Objects, Implementing HTTP Clients and
Servers in Node.js, Implementing HTTPS Servers and Clients. Using Additional Node.js Modules-Using
the OS Module, Using the util Module, Using the DNS Module, Using the crypto Module.

UNIT-III MongoDB:
Need of NoSQL, Understanding MongoDB, MongoDB Data Types, Planning Your Data Model, Building
the MongoDB Environment, Administering User Accounts, Configuring Access Control, Administering
Databases, Managing Collections, Adding the MongoDB Driver to Node.js, Connecting to MongoDB
from Node.js, Understanding the Objects Used in the MongoDB Node.js Driver, Accessing and
Manipulating Databases, Accessing and Manipulating Collections

UNIT-IV Express and Angular:


Getting Started with Express, Configuring Routes, Using Requests Objects, Using Response Objects.
Angular: importance of Angular, Understanding Angular, creating a Basic Angular Application, Angular
Components, Expressions, Data Binding, Built-in Directives, Custom Directives, Implementing Angular
Services in Web Applications.

UNIT-V React:
Need of React, Simple React Structure, The Virtual DOM, React Components, Introducing React
Components, Creating Components in React, Data and Data Flow in React, Rendering and Life Cycle
Methods in React, working with forms in React, integrating third party libraries, Routing in React

2
Full Stack Development (MERN)-CS631PE Department of CSE

UNIT-1
Understanding the Basic Web Development Framework
Web development frameworks provide a structured approach to building web applications, making
development faster, more efficient, and scalable. These frameworks handle routine tasks such as
routing, authentication, and database interaction, allowing developers to focus on business logic.
1. What is a Web Development Framework?
A web development framework is a collection of libraries, tools, and best practices that simplify the
development of web applications. It provides a foundation that developers can build upon instead of
coding everything from scratch.
Types of Web Development Frameworks
1. Front-end Frameworks – Used for UI development (e.g., React.js, Angular, Vue.js).
2. Back-end Frameworks – Used for server-side logic (e.g., Express.js, Spring Boot, Django).
3. Full-stack Frameworks – Include both front-end and back-end capabilities (e.g., Next.js,
Meteor).
2. Front-End Frameworks
Front-end frameworks help developers create interactive and responsive user interfaces.
Common Front-End Frameworks
Framework Language Features
React.js JavaScript Component-based, Virtual DOM, Hooks
Angular TypeScript MVC, Two-way Data Binding, Dependency Injection
Vue.js JavaScript Reactive Data Binding, Component-based
Core Concepts in Front-End Development
• HTML (Hypertext Markup Language) – Structure of a web page.
• CSS (Cascading Style Sheets) – Styling and layout.
• JavaScript (JS) – Interactivity and dynamic behaviour.
Tools for Front-End Development
• Webpack, Babel – Bundling and transfilling code.
• Tailwind CSS, Bootstrap – Pre-built styling frameworks.
• React Router – Handles navigation in React applications.
3. Back-End Frameworks
Back-end frameworks manage server-side logic, database interactions, and authentication.

3
Full Stack Development (MERN)-CS631PE Department of CSE

Common Back-End Frameworks


Framework Language Features
Express.js JavaScript (Node.js) Lightweight, Middleware, REST APIs
Spring Boot Java MVC, Dependency Injection, Microservices
Django Python ORM, Security, Built-in Admin
Core Concepts in Back-End Development
• Routing – Handling HTTP requests.
• Middleware – Processing requests (e.g., authentication).
• Database Interaction – SQL (PostgreSQL, MySQL) or NoSQL (MongoDB).
• Authentication – JWT, OAuth, Sessions.
Tools for Back-End Development
• Node.js & NPM – JavaScript runtime and package manager.
• Maven, Gradle – Dependency management for Java.
• Postman – API testing tool.
4. Full-Stack Development & Frameworks
A full-stack framework includes both front-end and back-end components.
Popular Full-Stack Frameworks
• Next.js (React + Node.js)
• Meteor (JavaScript Full Stack)
• Ruby on Rails (Ruby)
Key Full-Stack Technologies
Technology Purpose
RESTful APIs Communication between client & server
GraphQL Alternative to REST APIs for fetching data
JWT (JSON Web Token) Secure authentication mechanism
WebSocket’s Real-time communication

5. DevOps & Deployment


Deploying web applications efficiently is crucial for scalability.
Key Deployment Technologies
Tool/Service Purpose
Docker Containerization
Kubernetes Orchestration
AWS, Azure, GCP Cloud hosting
CI/CD (GitHub Actions, Jenkins) Automated deployment

4
Full Stack Development (MERN)-CS631PE Department of CSE

Detailed Explanation of Full-Stack Components (Node.js, MongoDB, Express, React, Angular) &
JavaScript Fundamentals
Full-stack development refers to the combination of both front-end and back-end technologies to build
a complete web application. This guide will cover essential full-stack components, including Node.js,
MongoDB, Express.js, React, Angular, and JavaScript fundamentals.
1. JavaScript Fundamentals
JavaScript is the core programming language used for full-stack development. Understanding its
fundamentals is essential before diving into frameworks like Node.js, React, Angular, and Express.
Key JavaScript Concepts
Concept Explanation
Variables Use var, let, and const to declare variables.
JavaScript has primitive types (string, number, boolean, null, undefined)
Data Types
and objects.
Define functions using function declarations, expressions, and arrow
Functions
functions (()=>{}).
Includes let/const, template literals, spread/rest operators,
ES6 Features
destructuring, promises, and async/await.
Methods like document.getElementById(), event listeners to
DOM Manipulation
manipulate HTML elements.
Event Handling Handling user interactions using addEventListener().
Uses callbacks, Promises, and async/await for handling async
Asynchronous JS
operations.
Closures & Scope Understanding block scope, function scope.
Object-Oriented
JavaScript supports prototype-based inheritance and ES6 class syntax.
Programming (OOP)
Modules Use import and export to organize code in ES6.
Error Handling Using try...catch for exception handling.

Here's a breakdown with examples for each concept:


1. Variables
Use var, let, and const to declare variables.
var oldVar = "Avoid using var"; // Function-scoped
let modernVar = "Use let for reassignable variables"; // Block-scoped
const constantVar = "Use const for constants"; // Block-scoped and immutable

2. Data Types
JavaScript has primitive types (string, number, boolean, null, undefined) and objects.
let str = "Hello"; // String
let num = 42; // Number
let isTrue = true; // Boolean
let empty = null; // Null
let notDefined; // Undefined
let obj = { key: "value" }; // Object

3. Functions
Define functions using function declarations, expressions, and arrow functions.
function regularFunction() { return "Hello"; } // Function declaration
const functionExpression = function () { return "Hello"; }; // Function expression

5
Full Stack Development (MERN)-CS631PE Department of CSE

const arrowFunction = () => "Hello"; // Arrow function (implicit return)

4. ES6 Features
Modern JavaScript features.
let name = "John";
console.log(`Hello, ${name}!`); // Template literals
let arr = [1, 2, 3];
let newArr = [...arr, 4]; // Spread operator
const person = { firstName: "John", lastName: "Doe" };
const { firstName, lastName } = person; // Object destructuring
const fetchData = async () => {
let data = await fetch("https://api.example.com");
return data.json();
}; // Async/Await
5. DOM Manipulation
Modify HTML elements dynamically.
document.getElementById("demo").innerText = "Hello, World!";
document.querySelector(".my-class").style.color = "red";

6. Event Handling
Handle user interactions.
document.getElementById("btn").addEventListener("click", () => {
alert("Button Clicked!");
});

7. Asynchronous JS
Use callbacks, Promises, and async/await.
setTimeout(() => console.log("Executed after 2 seconds"), 2000); // Callback

fetch("https://api.example.com")
.then(response => response.json()) // Promise
.then(data => console.log(data))
.catch(error => console.error(error));

async function fetchData() {


try {
let response = await fetch("https://api.example.com");
let data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
} // Async/Await

8. Closures & Scope


Understand lexical scope and closures.
function outer() {
let count = 0;
return function inner() {
count++;

6
Full Stack Development (MERN)-CS631PE Department of CSE

console.log(count);
};
}
const counter = outer();
counter(); // 1
counter(); // 2

9. Object-Oriented Programming (OOP)


Prototype-based inheritance and ES6 class syntax.
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
const john = new Person("John");
john.greet(); // Hello, my name is John

10. Modules
Organize code using import and export.
// module.js
export const greet = () => console.log("Hello!");

// main.js
import { greet } from "./module.js";
greet();

11. Error Handling


Use try...catch for exception handling.
try {
let result = JSON.parse("Invalid JSON");
} catch (error) {
console.error("Error:", error.message);
}

2. Node.js
Node.js is a runtime environment that allows JavaScript to run on the server-side. It is built on the V8
engine (same engine used in Chrome).
Why Use Node.js?
• Non-blocking, event-driven architecture
• Uses JavaScript for both front-end and back-end
• Fast execution speed due to the V8 engine
• Large ecosystem with NPM packages
Core Features of Node.js

7
Full Stack Development (MERN)-CS631PE Department of CSE

Feature Explanation
Single-threaded Event
Handles multiple requests asynchronously using an event-driven model.
Loop
Modules Built-in modules (fs, http, path), and third-party modules via npm.
Express.js A lightweight framework to build APIs and web applications.
File System Access Read and write files using the fs module.
Streams Handles large files efficiently.
Web Sockets Real-time communication using socket.io.

Example: Simple Node.js HTTP Server


const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, World!');
});
server.listen(3000, () => {
console.log('Server running on port 3000');
});

3. Express.js
Express.js is a lightweight Node.js framework for building web applications and APIs.
Why Use Express?
• Simplifies routing and request handling
• Middleware support for logging, authentication, and more
• Supports RESTful APIs
Core Features of Express.js
Feature Explanation
Routing Define application endpoints (app.get(), app.post()).
Middleware Functions that process requests (e.g., authentication, logging).
Template Engines Use EJS, Handlebars, or Pug for rendering views.
Static File Serving Serve static files like CSS and images.
Example: Simple Express.js Server
const express = require('express');
const app = express();

app.get('/', (req, res) => {


res.send('Hello, Express!');
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

4. MongoDB
MongoDB is a NoSQL database that stores data in JSON-like documents.
Why Use MongoDB?

8
Full Stack Development (MERN)-CS631PE Department of CSE

• Schema-less, allowing flexible data storage


• Scales horizontally
• Works well with JavaScript (uses BSON format)
Core Features of MongoDB
Feature Explanation
Collections & Documents Data is stored in collections (like tables) and documents (like rows).
CRUD Operations Create, Read, Update, and Delete documents.
Indexes Improve query performance.
Aggregation Framework Used for complex queries and analytics.

Example: Connecting Express.js to MongoDB


const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydb', {
useNewUrlParser: true, useUnifiedTopology: true
})
.then(() => console.log('MongoDB Connected'))
.catch(err => console.error(err));

5. React.js
React.js is a popular JavaScript library for building UI components.
Why Use React?
• Component-based architecture
• Virtual DOM for efficient rendering
• Supports hooks and functional components

Core Features of React.js


Feature Explanation

Components Reusable UI elements.

State & Props Manage dynamic data.

Hooks useState(), useEffect(), useContext().

React Router Handles navigation in SPAs.


Example: React Component
import React from 'react';

function App () {
return <h1>Hello, React! </h1>;
}
export default App;
6. Angular
Angular is a TypeScript-based framework for building web applications.
Why Use Angular?
• Built-in support for MVC architecture
• Two-way data binding
• Dependency Injection

9
Full Stack Development (MERN)-CS631PE Department of CSE

Core Features of Angular


Feature Explanation
Modules & Components Organize the application structure.
Directives Modify the behaviour of elements.
Services & Dependency Injection Share data across components.
Example: Angular Component
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
template: `<h1>Hello, Angular!</h1>`
})
export class AppComponent {}

Install Node.js
Step 1: Download Node.js
1. Go to the official Node.js website.
2. You will see two versions:
o LTS (Long Term Support): Recommended for most users and production
environments.
o Current: The latest features, but may not be as stable.
3. Click on the appropriate version for your operating system (Windows, macOS, or Linux).

Step 2: Install Node.js


For Windows:
1. Download the .msi installer from the Node.js website.
2. Run the installer and follow the setup wizard.
3. Select "Next" to accept the default settings.
4. Check the box to install npm (Node Package Manager) (it comes bundled with Node.js).
5. Click "Install" and wait for the installation to complete.
6. Click "Finish" when done.
For macOS:
1. Download the .pkg file from the Node.js website.
2. Open the file and follow the installation instructions.
3. Once installed, Node.js and npm will be available in the terminal.
For Linux (Ubuntu/Debian-based):
1. Open the terminal.
2. Run the following commands:
3. sudo apt update
4. sudo apt install -y nodejs npm
5. To install a newer version, use Node Version Manager (nvm):
6. curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
7. source ~/.bashrc
8. nvm install --lts

Step 3: Verify Installation


Once installed, open a terminal or command prompt and type:
node -v
This will display the installed Node.js version.
npm -v

10
Full Stack Development (MERN)-CS631PE Department of CSE

This will display the installed npm version.

Step 4: Test Node.js


To confirm Node.js is working, create a simple JavaScript file:
1. Open a text editor and create a file named test.js.
2. Add the following code:
3. console.log ("Node.js is installed successfully!");
4. Save the file and run it in the terminal:
5. node test.js
6. If you see the message "Node.js is installed successfully!", you have successfully installed
Node.js!
Working with Node.js Packages (npm)
Node.js uses npm (Node Package Manager) to manage packages (libraries and dependencies). Below
are key topics with examples to help you get started.
1. Checking npm Version
Before using npm, ensure it’s installed:
npm -v
If npm is not installed, reinstall Node.js from nodejs.org.
2. Initializing a Node.js Project (package.json)
A package.json file manages project dependencies and metadata.
Method 1: Manual Creation
Run the following command:
npm init
It will ask several questions (name, version, description, entry point, etc.). You can press Enter to accept
defaults or provide custom values.
Method 2: Quick Creation
Use the -y flag to generate a package.json file with default values:
npm init -y
Example package.json File:
{
"name": "my-node-app",
"version": "1.0.0",
"description": "A sample Node.js app",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {},
"devDependencies": {}
}

3. Installing Packages
A. Installing a Package Globally
Some tools (like nodemon) are installed globally to be used system-wide:
npm install -g nodemon
You can now use nodemon from the terminal.
B. Installing a Package Locally
To install a package only for a specific project (e.g., express):
npm install express
This adds express to node_modules and updates package.json.
C. Installing Dev Dependencies

11
Full Stack Development (MERN)-CS631PE Department of CSE

For packages needed only during development (e.g., testing tools like jest):
npm install --save-dev jest
These are saved under devDependencies in package.json.
4. Using Installed Packages
After installing express, create a file (server.js) and use it:
const express = require('express');
const app = express();

app.get('/', (req, res) => {


res.send('Hello, Node.js with Express!');
});

app.listen(3000, () => console.log('Server running on port 3000'));


Run the server:
node server.js
Visit http://localhost:3000/ in a browser.

5. Managing Packages
A. Checking Installed Packages
List installed dependencies:
npm list
List globally installed packages:
npm list -g --depth=0
B. Updating Packages
To update all dependencies to the latest compatible versions:
npm update
To update a specific package:
npm update express
C. Removing a Package
Uninstall a package:
npm uninstall express
If removing a dev dependency:
npm uninstall jest --save-dev

6. Using package-lock.json and node_modules


• package-lock.json locks dependency versions to ensure consistent installs across
environments.
• node_modules/ contains installed dependencies (it should not be committed to Git; use
.gitignore).
To reinstall all dependencies from package.json:
npm install

7. Running Scripts
Define scripts inside package.json:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}

Run the script using npm:


npm run start

12
Full Stack Development (MERN)-CS631PE Department of CSE

For development with nodemon:


npm run dev

8. Using npx (Execute Packages Without Installing)


To run a package without installing it globally, use npx. Example:
npx create-react-app my-app
This creates a React project without needing a global install.

Conclusion of the npm package


• Use npm install to add dependencies.
• Use npm uninstall to remove packages.
• Use npm update to update dependencies.
• Use npm run <script> to run scripts defined in package.json.

Understanding the Node.js Event Model,


Adding Work to the Event Queue,
Implementing Callbacks

Node.js operates on a non-blocking, event-driven architecture, allowing it to efficiently handle


multiple tasks asynchronously. This is made possible through the Event Loop, which processes tasks in
the Event Queue and executes callbacks when operations complete.

1. Understanding the Node.js Event Model


Node.js uses an event-driven architecture where operations (like reading files, making network
requests, or handling user input) are processed asynchronously. Instead of waiting for one operation
to finish before moving to the next, Node.js continues executing other tasks and calls a callback
function when the operation is done.

Key Concepts of the Event Model:


• Event Loop → Manages asynchronous operations and executes callbacks.
• Event Queue → Stores tasks waiting to be executed.
• Callbacks → Functions executed when an operation completes.
• Timers & Immediate Execution → setTimeout(), setImmediate(), and process.nextTick() allow
scheduling tasks.
• EventEmitter → Used to handle custom events in Node.js.
2. Adding Work to the Event Queue

When an asynchronous operation is triggered (e.g., fs.readFile(), setTimeout(), or database queries),


Node.js adds it to the Event Queue so the main thread can continue executing other tasks. Once the
operation completes, the event loop processes it and executes the corresponding callback.
Example: Non-Blocking Behavior

console.log('Start');
setTimeout(() => {
console.log('Task added to Event Queue');
}, 2000);

console.log('End');

Execution Flow:
1. Start is printed.

13
Full Stack Development (MERN)-CS631PE Department of CSE

2. setTimeout() schedules a task to execute after 2 seconds.


3. End is printed immediately (without waiting for 2 seconds).
4. After 2 seconds, Task added to Event Queue executes.
Output:
Start
End
Task added to Event Queue

3. Implementing Callbacks
A callback is a function that is passed as an argument to another function and is executed when an
asynchronous operation completes.
Example: Callback in File Reading
const fs = require('fs');

console.log('Start');

fs.readFile('file.txt', 'utf8', (err, data) => {


if (err) {
console.error('Error reading file:', err);
return;
}
console.log('File Content:', data);
});

console.log('End');
Execution Flow:
1. Start is printed.
2. fs.readFile() starts reading the file but doesn’t block execution.
3. End is printed immediately.
4. Once the file read completes, the callback executes and prints File Content.
Output:
Start
End
File Content: <content of file.txt>

4. The Node.js Event Loop

The Event Loop is the core of Node.js’s asynchronous behavior. It continuously checks the Event Queue
for pending tasks and executes them.
Event Loop Phases:
1. Timers → Executes setTimeout() and setInterval() callbacks.
2. I/O Callbacks → Executes callbacks from completed I/O operations (like fs.readFile()).
3. Idle & Prepare → Internal processing.
4. Poll → Fetches new I/O events, waiting for new tasks.
5. Check → Executes setImmediate() callbacks.
6. Close Callbacks → Executes close event callbacks (like socket.on('close')).

5. Using process.nextTick(), setTimeout(), and setImmediate()


1. process.nextTick()
Executes callbacks before the next event loop iteration.
console.log('Start');

14
Full Stack Development (MERN)-CS631PE Department of CSE

process.nextTick(() => {
console.log('Next Tick Callback');
});
console.log('End');
Output:
Start
End
Next Tick Callback
process.nextTick() ensures the callback runs before any I/O operations or setTimeout().

2. setTimeout() vs. setImmediate()


• setTimeout(fn, 0) runs after the poll phase.
• setImmediate(fn) runs immediately after I/O callbacks.
console.log('Start');

setTimeout(() => console.log('setTimeout Callback'), 0);


setImmediate(() => console.log('setImmediate Callback'));

console.log('End');
Output: (Order may vary)
Start
End
setImmediate Callback
setTimeout Callback

Why?
• setImmediate(): executes after the poll phase.
• setTimeout(0): executes after a minimal delay but still waits for the poll phase to clear.

6. Event-Driven Programming with EventEmitter


Node.js has an EventEmitter module for handling custom events.
Example: Creating and Triggering Events
const EventEmitter = require('events');
const emitter = new EventEmitter();

emitter.on('greet', (name) => {


console.log (`Hello, ${name}! `);
});

emitter.emit('greet', 'Alice');
Output:
Hello, Alice!
Example: Handling Multiple Event Listeners
emitter.on('data', (msg) => console.log(`Listener 1: ${msg}`));
emitter.on('data', (msg) => console.log(`Listener 2: ${msg}`));

emitter.emit('data', 'Event Model in Action');


Output:
Listener 1: Event Model in Action
Listener 2: Event Model in Action

15
Full Stack Development (MERN)-CS631PE Department of CSE

7. Avoiding Callback Hell with Promises


Callback nesting leads to callback hell, making code unreadable.
Callback Hell Example

fs.readFile('file1.txt', 'utf8', (err, data1) => {


if (err) throw err;
fs.readFile('file2.txt', 'utf8', (err, data2) => {
if (err) throw err;
fs.readFile('file3.txt', 'utf8', (err, data3) => {
if (err) throw err;
console.log(data1, data2, data3);
});
});
});
Using Promises improves readability:
const fs = require('fs').promises;

async function readFiles() {


try {
const data1 = await fs.readFile('file1.txt', 'utf8');
const data2 = await fs.readFile('file2.txt', 'utf8');
const data3 = await fs.readFile('file3.txt', 'utf8');
console.log(data1, data2, data3);
} catch (err) {
console.error(err);
}
}

readFiles();

Advantages of Promises:
• Avoids deep nesting.
• Improves readability.
• Easier error handling using try...catch.

Conclusion
• Node.js Event Model allows non-blocking execution.
• Event Queue stores asynchronous tasks.
• Callbacks execute when an operation completes.
• Event Loop efficiently manages queued tasks.
• Promises & async/await simplify handling asynchronous code.

Web References
1. https://www.geeksforgeeks.org/nodejs/?ref=lbp
2. https://nodejs.org/api/fs.html
3. https://www.tpointtech.com/nodejs-file-system
4. https://www.geeksforgeeks.org/mern-stack/

16
Full Stack Development (MERN)-CS631PE Department of CSE

UNIT-III

MongoDB Data Types:

MongoDB stores data using BSON (Binary JSON), which supports a variety of data types
beyond standard JSON. Here are some key MongoDB data types:
• String: Used for storing text data (UTF-8 format).
• Integer: Supports both 32-bit and 64-bit signed integers.
• Double: Stores floating-point numbers.
• Boolean: Represents true or false values.
• Null: Represents missing or undefined values.
• ObjectId: A unique identifier for documents.
• Date: Stores date and time values

Planning Your Data Model in mongodb

Planning your data model in MongoDB is crucial for optimizing performance and
scalability. Since MongoDB is a document-oriented NoSQL database, its schema
design differs significantly from relational databases. Here are some key
considerations:
1. Understand Your Application's Workload
• Identify how your application queries and updates data.
• Optimize for read-heavy or write-heavy operations.
2. Choose Between Embedded vs. Normalized Data Models
• Embedded Model: Stores related data within a single document, improving
read performance but potentially increasing redundancy.
• Normalized Model: Uses references between documents, reducing duplication
but requiring additional queries.
3. Apply Schema Design Patterns
• Bucket Pattern: Groups related data into a single document to reduce query
overhead.
• Extended Reference Pattern: Stores frequently accessed data within a
document while keeping detailed data in separate collections.
4. Indexing for Performance
• Use indexes to speed up queries but avoid excessive indexing, which can
impact write performance.
5. Plan for Scalability
• Consider sharding strategies if your dataset grows significantly.
You can explore more details in the MongoDB documentation.

Administering User Accounts in mongo db

Administering user accounts in MongoDB involves managing authentication, roles, and


permissions to ensure secure access control. Here are the key steps:
1. Creating a User
MongoDB allows you to create users with specific roles using the db.createUser()
method:

17
Full Stack Development (MERN)-CS631PE Department of CSE

db.createUser({
user: "adminUser",
pwd: "securePassword",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})
This creates an admin user with privileges to manage users across all databases.
2. Assigning Roles
MongoDB provides built-in roles such as:
• read: Allows read-only access.
• readWrite: Grants permission to read and write data.
• dbAdmin: Enables database administration tasks.
• userAdmin: Allows user management.
• clusterAdmin: Grants control over cluster-wide operations.
You can also create custom roles using db.createRole().
3. Listing Users
To view existing users in a database:
db.getUsers()
4. Updating User Credentials
To change a user's password:
db.changeUserPassword("adminUser", "newSecurePassword")
5. Deleting a User
To remove a user:
db.dropUser("adminUser")

Configuring access control in MongoDB ensures that only authorized users can interact with
the database. Here’s how you can set it up:
1. Enable Authentication
MongoDB requires authentication to restrict access. Start MongoDB with the --auth flag:
mongod --auth --port 27017 --dbpath /data/db
This ensures that users must authenticate before accessing the database.
2. Create an Admin User
Use the createUser() method to add an admin user:
use admin
db.createUser({
user: "adminUser",
pwd: "securePassword",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})
This user will have privileges to manage other users.
3. Assign Roles
MongoDB provides built-in roles such as:
• read: Allows reading data.
• readWrite: Allows reading and writing data.
• dbAdmin: Grants database administration privileges.
• userAdmin: Allows managing users.
You can also create custom roles using createRole().

18
Full Stack Development (MERN)-CS631PE Department of CSE

4. Configure IP Whitelisting
Restrict access to trusted IPs by modifying the mongod.conf file:
net:
bindIp: 127.0.0.1,192.168.1.100
This ensures only specified IPs can connect.
5. Use TLS/SSL for Secure Connections
Enable TLS/SSL encryption to protect data in transit:
mongod --sslMode requireSSL --sslPEMKeyFile /etc/ssl/mongodb.pem

Managing collections in MongoDB involves creating, updating, deleting, and querying data
efficiently. Here’s a breakdown:
1. Creating a Collection
MongoDB automatically creates collections when you insert data, but you can explicitly create
one using:
db.createCollection("users")
You can also specify options like validation rules.
2. Inserting Documents
Add a single document:
db.users.insertOne({ name: "Sai", age: 25 })
Insert multiple documents:
db.users.insertMany([{ name: "Kishore", age: 30 }, { name: "Aditi", age: 28 }])
3. Querying Data
Find all documents:
db.users.find({})
Find specific documents:
db.users.find({ age: { $gt: 25 } })
4. Updating Documents
Modify a single document:
db.users.updateOne({ name: "Sai" }, { $set: { age: 26 } })
Update multiple documents:
db.users.updateMany({}, { $inc: { age: 1 } })
5. Deleting Documents
Remove a single document:
db.users.deleteOne({ name: "Sai" })
Delete multiple documents:
db.users.deleteMany({ age: { $lt: 25 } })
6. Dropping a Collection
To delete an entire collection:
db.users.drop()
To connect Node.js to MongoDB, follow these steps:
1. Install the MongoDB Driver
Run the following command in your Node.js project:
npm install mongodb
This installs the official MongoDB Node.js driver.

19
Full Stack Development (MERN)-CS631PE Department of CSE

2. Connect to MongoDB
Create a connection using the MongoDB client:
const { MongoClient } = require("mongodb");

const uri = "mongodb://localhost:27017";


const client = new MongoClient(uri);

async function connectDB() {


try {
await client.connect();
console.log("Connected to MongoDB!");
} catch (error) {
console.error("Connection failed:", error);
}
}
connectDB();
This establishes a connection to a local MongoDB instance.
3. Using Mongoose (Optional)
Mongoose simplifies MongoDB interactions. Install it using:
npm install mongoose
Then, connect using:
const mongoose = require("mongoose");

mongoose.connect("mongodb://localhost:27017/myDatabase", {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => console.log("Connected to MongoDB!"))
.catch(err => console.error("Connection error:", err));
Mongoose provides schema validation and easier data handling.
Understanding the Objects Used in the MongoDB Node.js Driver
The MongoDB Node.js driver provides several key objects to interact with MongoDB efficiently. Here
are the most important ones:
1. MongoClient
The MongoClient object is used to establish a connection to MongoDB.
const { MongoClient } = require("mongodb");
const client = new MongoClient("mongodb://localhost:27017");
It allows you to connect to a MongoDB instance and perform operations.
2. Db
The Db object represents a specific database within MongoDB.
const db = client.db("myDatabase");
You use this object to interact with collections and execute queries.
3. Collection
The Collection object represents a collection within a database.
const users = db.collection("users");
It provides methods for inserting, updating, deleting, and querying documents.
4. Cursor
A Cursor object is returned when querying data, allowing iteration over results.
const cursor = users.find({ age: { $gt: 25 } });
cursor.forEach(doc => console.log(doc));

20
Full Stack Development (MERN)-CS631PE Department of CSE

It helps efficiently process large datasets.


5. ObjectId
The ObjectId is a unique identifier for MongoDB documents.
const { ObjectId } = require("mongodb");
const id = new ObjectId();
console.log(id);
It ensures uniqueness across collections.

Accessing and manipulating databases in MongoDB is straightforward and powerful. Here's a


practical breakdown to get you rolling:
Accessing Databases
• Switch to a database (or create one if it doesn’t exist yet):
• use myDatabase
MongoDB creates the database only when you insert data into it.
• List all databases:
• show dbs
• Check current database:
• db

Manipulating Databases
• Create a new database: Just switch to it and insert data.
• use newDB
• db.myCollection.insertOne({ name: "Sai" })
• Drop a database:
• db.dropDatabase()

Working with Collections


Create a collection:
db.createCollection("users")
Insert documents:
db.users.insertOne({ name: "Kishore", age: 25 })
Query documents:
db.users.find({ age: { $gt: 20 } })
Update documents:
db.users.updateOne({ name: "Kishore" }, { $set: { age: 26 } })
Delete documents:
db.users.deleteOne({ name: "Kishore" })
Drop a collection:
db.users.drop()

21
Full Stack Development (MERN)-CS631PE Department of CSE

Unit -2
1. Working with JSON in Node.js
JSON (JavaScript Object Notation) is a lightweight format for storing and transporting data. In
Node.js, it's commonly used for configuration files, APIs, and data exchange.
Key Operations:
• JSON.stringify(): Converts a JavaScript object to a JSON string.
• JSON.parse(): Converts a JSON string back to a JavaScript object.
Example:
const user = { name: "Sai", age: 25 };

// Convert object to JSON string


const jsonString = JSON.stringify(user);
console.log(jsonString); // {"name":"Sai","age":25}

// Convert JSON string back to object


const parsedUser = JSON.parse(jsonString);
console.log(parsedUser.name); // Sai
This is especially useful when sending or receiving data via HTTP or saving to files.

2. Using the Buffer Module to Buffer Data


Buffers are used to handle binary data directly in memory. This is essential when working with
streams, files, or network protocols.
Why Buffers?
JavaScript strings are UTF-16 encoded, but binary data (like images or files) needs byte-level
manipulation. Buffers provide that low-level access.
Creating Buffers:
const buf = Buffer.from("Hello, Sai!");
console.log(buf); // <Buffer 48 65 6c 6c 6f 2c 20 53 61 69 21>
console.log(buf.toString()); // Hello, Sai!
Convert JSON to Buffer and Back:
const obj = { message: "Hello" };
const buffer = Buffer.from(JSON.stringify(obj));
const restored = JSON.parse(buffer.toString());
console.log(restored.message); // Hello
Buffers are also used in file I/O and network communication for performance and memory
efficiency.
3. Using the Stream Module to Stream Data
Streams allow you to process data piece by piece instead of loading it all at once—perfect for
large files or real-time data.
Types of Streams:
• Readable: For reading data (e.g., from a file).
• Writable: For writing data (e.g., to a file).
• Duplex: Both readable and writable.
• Transform: Modifies data as it’s read or written.
Reading a File with Streams:
const fs = require("fs");
const readStream = fs.createReadStream("input.txt", "utf8");

22
Full Stack Development (MERN)-CS631PE Department of CSE

readStream.on("data", chunk => {


console.log("Chunk received:", chunk);
});

readStream.on("end", () => {
console.log("Finished reading.");
});
Writing to a File with Streams:
const writeStream = fs.createWriteStream("output.txt");

writeStream.write("Hello, Sai!\n");
writeStream.write("Streaming is efficient.\n");
writeStream.end();
This approach is memory-efficient and ideal for handling large datasets or real-time
applications like video streaming or chat servers.

1. Importing the File System Module


const fs = require("fs");

2. Creating or Opening a File


Using fs.open()
Opens a file for reading or writing. If it doesn’t exist, it creates one.
fs.open("example.txt", "w", (err, file) => {
if (err) throw err;
console.log("File opened or created!");
});
• "w" means write mode. Other flags include "r" (read), "a" (append), etc.

3. Writing to a File
Using fs.writeFile()
Overwrites the file or creates it if it doesn’t exist.
fs.writeFile("example.txt", "Hello, Sai!", err => {
if (err) throw err;
console.log("File written successfully!");
});
Using fs.appendFile()
Adds content to the end of the file.
fs.appendFile("example.txt", "\nAppended line.", err => {
if (err) throw err;
console.log("Content appended!");
});

4. Reading from a File


Using fs.readFile()
Reads the entire file asynchronously.

23
Full Stack Development (MERN)-CS631PE Department of CSE

fs.readFile("example.txt", "utf8", (err, data) => {


if (err) throw err;
console.log("File content:\n", data);
});

5. Closing a File
When using fs.open(), you can close the file descriptor manually:
fs.open("example.txt", "r", (err, fd) => {
if (err) throw err;
console.log("File opened!");

fs.close(fd, err => {


if (err) throw err;
console.log("File closed!");
});
});

6. Deleting a File
Using fs.unlink()
fs.unlink("example.txt", err => {
if (err) throw err;
console.log("File deleted!");
});

7. Other File System Tasks


Renaming a File
fs.rename("oldname.txt", "newname.txt", err => {
if (err) throw err;
console.log("File renamed!");
});
Checking if a File Exists
fs.access("example.txt", fs.constants.F_OK, err => {
console.log(err ? "File does not exist" : "File exists");
});

Bonus: Using Promises with fs.promises


const fsPromises = require("fs").promises;

async function readFileAsync() {


try {
const data = await fsPromises.readFile("example.txt", "utf8");
console.log(data);
} catch (err) {
console.error(err);
}
}
readFileAsync();

24
Full Stack Development (MERN)-CS631PE Department of CSE

Implementing HTTP services in Node.js involves handling requests, processing URLs, and
responding to clients efficiently. Let’s break it down step by step:

1. Setting Up an HTTP Server


Node.js provides the built-in http module to create an HTTP server.
Example: Basic HTTP Server
const http = require("http");

const server = http.createServer((req, res) => {


res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello, Sai! Welcome to Node.js HTTP services.");
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• http.createServer() creates a server.
• res.writeHead(200, { "Content-Type": "text/plain" }) sets the response header.
• res.end() sends the response and closes the connection.
• server.listen(3000) starts the server on port 3000.

2. Processing URLs in Node.js


To extract and process URL parameters, we use the url module.
Example: Parsing URL Parameters
const http = require("http");
const url = require("url");

const server = http.createServer((req, res) => {


const parsedUrl = url.parse(req.url, true);
const name = parsedUrl.query.name || "Guest";

res.writeHead(200, { "Content-Type": "text/plain" });


res.end(`Hello, ${name}!`);
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• url.parse(req.url, true) extracts query parameters.
• parsedUrl.query.name retrieves the name parameter from the URL.
• Example request: http://localhost:3000/?name=Sai → Response: "Hello, Sai!"

3. Handling Different Routes


You can define multiple routes to serve different responses.
Example: Routing Requests
const http = require("http");
const url = require("url");

25
Full Stack Development (MERN)-CS631PE Department of CSE

const server = http.createServer((req, res) => {


const parsedUrl = url.parse(req.url, true);
const pathname = parsedUrl.pathname;

res.writeHead(200, { "Content-Type": "text/plain" });

if (pathname === "/about") {


res.end("Welcome to the About Page!");
} else if (pathname === "/contact") {
res.end("Contact us at contact@example.com");
} else {
res.end("Home Page");
}
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• pathname === "/about" serves the About page.
• pathname === "/contact" serves the Contact page.
• Default response serves the Home page.
4. Handling POST Requests
For handling form submissions or API requests, use req.on("data") to process incoming data.
Example: Handling POST Data
const http = require("http");

const server = http.createServer((req, res) => {


if (req.method === "POST") {
let body = "";

req.on("data", chunk => {


body += chunk;
});

req.on("end", () => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(`Received Data: ${body}`);
});
} else {
res.writeHead(405, { "Content-Type": "text/plain" });
res.end("Only POST requests are allowed.");
}
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");

26
Full Stack Development (MERN)-CS631PE Department of CSE

});
• req.on("data", chunk => { body += chunk; }) collects incoming data.
• req.on("end", () => { res.end(body); }) sends the processed data back.

5. Using Express for Simplified HTTP Services


Instead of manually handling requests, Express.js makes routing easier.
Example: Express Server with Routes
const express = require("express");
const app = express();

app.get("/", (req, res) => res.send("Home Page"));


app.get("/about", (req, res) => res.send("About Page"));
app.post("/submit", (req, res) => res.send("Form Submitted"));

app.listen(3000, () => console.log("Express server running on http://localhost:3000"));


• app.get("/about", (req, res) => res.send("About Page")) handles GET requests.
• app.post("/submit", (req, res) => res.send("Form Submitted")) handles POST requests.

Processing Query Strings and Form Parameters

Processing query strings and form parameters in Node.js is essential for handling user input
in web applications. Let’s break it down step by step with examples.
1. Understanding Query Strings
Query strings are appended to URLs after a ? and contain key-value pairs separated by &.
Example URL with Query String:
http://localhost:3000/?name=Sai&age=25
Here, name=Sai and age=25 are query parameters.
Extracting Query Parameters in Node.js
Using the built-in url module:
const http = require("http");
const url = require("url");

const server = http.createServer((req, res) => {


const parsedUrl = url.parse(req.url, true);
const queryParams = parsedUrl.query;

res.writeHead(200, { "Content-Type": "text/plain" });


res.end(`Hello, ${queryParams.name}! You are ${queryParams.age} years old.`);
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• url.parse(req.url, true) extracts query parameters.
• parsedUrl.query holds the key-value pairs.

2. Using the querystring Module

27
Full Stack Development (MERN)-CS631PE Department of CSE

The querystring module provides utilities for parsing and formatting query strings.
Parsing Query Strings
const querystring = require("querystring");

const query = "name=Sai&age=25";


const parsedQuery = querystring.parse(query);

console.log(parsedQuery.name); // Sai
console.log(parsedQuery.age); // 25
Stringifying Objects into Query Strings
const obj = { name: "Sai", age: 25 };
const queryString = querystring.stringify(obj);

console.log(queryString); // "name=Sai&age=25"
This is useful when constructing URLs dynamically.

3. Handling Form Parameters in Node.js


Form data is sent via POST requests and must be processed from the request body.
Example: Handling Form Data
const http = require("http");

const server = http.createServer((req, res) => {


if (req.method === "POST") {
let body = "";

req.on("data", chunk => {


body += chunk;
});

req.on("end", () => {
const parsedBody = querystring.parse(body);
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(`Received: ${parsedBody.name}, Age: ${parsedBody.age}`);
});
} else {
res.writeHead(405, { "Content-Type": "text/plain" });
res.end("Only POST requests are allowed.");
}
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• req.on("data", chunk => { body += chunk; }) collects incoming data.
• querystring.parse(body) converts form data into an object.

4. Using Express for Easier Form Handling

28
Full Stack Development (MERN)-CS631PE Department of CSE

Instead of manually parsing data, Express.js simplifies form handling.


Example: Handling Query Strings in Express
const express = require("express");
const app = express();

app.get("/", (req, res) => {


res.send(`Hello, ${req.query.name}! You are ${req.query.age} years old.`);
});

app.listen(3000, () => console.log("Express server running on http://localhost:3000"));


• req.query.name extracts query parameters.
Example: Handling Form Data in Express
const express = require("express");
const app = express();

app.use(express.urlencoded({ extended: true }));

app.post("/submit", (req, res) => {


res.send(`Received: ${req.body.name}, Age: ${req.body.age}`);
});

app.listen(3000, () => console.log("Express server running on http://localhost:3000"));


• express.urlencoded({ extended: true }) parses form data automatically.

Understanding Request, Response, and Server Objects in node js with detail explanation

1. Server Object in Node.js


The server object represents an HTTP server that listens for incoming requests and sends
responses.
Creating a Basic Server
const http = require("http");

const server = http.createServer((req, res) => {


res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello, Sai! Welcome to Node.js HTTP services.");
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• http.createServer() creates an HTTP server.
• res.writeHead(200, { "Content-Type": "text/plain" }) sets the response header.
• res.end() sends the response and closes the connection.
• server.listen(3000) starts the server on port 3000.

29
Full Stack Development (MERN)-CS631PE Department of CSE

2. Request Object (req)


The request object contains details about the incoming HTTP request, such as method,
headers, and query parameters.
Extracting Request Details
const http = require("http");

const server = http.createServer((req, res) => {


console.log("Method:", req.method);
console.log("URL:", req.url);
console.log("Headers:", req.headers);

res.writeHead(200, { "Content-Type": "text/plain" });


res.end("Request details logged.");
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• req.method retrieves the HTTP method (GET, POST, etc.).
• req.url provides the requested URL.
• req.headers contains request headers.

3. Processing Query Strings


Query strings are appended to URLs after a ? and contain key-value pairs.
Example URL with Query String
http://localhost:3000/?name=Sai&age=25
Extracting Query Parameters
const url = require("url");

const server = http.createServer((req, res) => {


const parsedUrl = url.parse(req.url, true);
const queryParams = parsedUrl.query;

res.writeHead(200, { "Content-Type": "text/plain" });


res.end(`Hello, ${queryParams.name}! You are ${queryParams.age} years old.`);
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• url.parse(req.url, true) extracts query parameters.
• parsedUrl.query holds the key-value pairs.

4. Response Object (res)


The response object is used to send data back to the client.
Sending a JSON Response
const server = http.createServer((req, res) => {

30
Full Stack Development (MERN)-CS631PE Department of CSE

const user = { name: "Sai", age: 25 };

res.writeHead(200, { "Content-Type": "application/json" });


res.end(JSON.stringify(user));
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• res.writeHead(200, { "Content-Type": "application/json" }) sets the response type.
• JSON.stringify(user) converts the object into a JSON string.

5. Handling POST Requests


For handling form submissions or API requests, use req.on("data") to process incoming data.
Example: Handling POST Data
const http = require("http");

const server = http.createServer((req, res) => {


if (req.method === "POST") {
let body = "";

req.on("data", chunk => {


body += chunk;
});

req.on("end", () => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(`Received Data: ${body}`);
});
} else {
res.writeHead(405, { "Content-Type": "text/plain" });
res.end("Only POST requests are allowed.");
}
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• req.on("data", chunk => { body += chunk; }) collects incoming data.
• req.on("end", () => { res.end(body); }) sends the processed data back.

6. Using Express for Simplified HTTP Services


Instead of manually handling requests, Express.js makes routing easier.
Example: Express Server with Routes
const express = require("express");
const app = express();

31
Full Stack Development (MERN)-CS631PE Department of CSE

app.get("/", (req, res) => res.send("Home Page"));


app.get("/about", (req, res) => res.send("About Page"));
app.post("/submit", (req, res) => res.send("Form Submitted"));

app.listen(3000, () => console.log("Express server running on http://localhost:3000"));


• app.get("/about", (req, res) => res.send("About Page")) handles GET requests.
• app.post("/submit", (req, res) => res.send("Form Submitted")) handles POST requests.

Implementing HTTP Clients and Servers in Node.js

Implementing HTTP Clients and Servers in Node.js involves creating a server that listens for
requests and a client that sends requests. Let's break it down step by step.
1. Creating an HTTP Server in Node.js
Node.js provides the built-in http module to create an HTTP server.
Example: Basic HTTP Server
const http = require("http");

const server = http.createServer((req, res) => {


res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello, Sai! Welcome to Node.js HTTP services.");
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• http.createServer() creates an HTTP server.
• res.writeHead(200, { "Content-Type": "text/plain" }) sets the response header.
• res.end() sends the response and closes the connection.
• server.listen(3000) starts the server on port 3000.

2. Creating an HTTP Client in Node.js


An HTTP client sends requests to a server and processes responses.
Example: Making a GET Request
const http = require("http");

http.get("http://localhost:3000", res => {


let data = "";

res.on("data", chunk => {


data += chunk;
});

res.on("end", () => {
console.log("Response from server:", data);
});
});
• http.get() sends a GET request to the server.

32
Full Stack Development (MERN)-CS631PE Department of CSE

• res.on("data", chunk => { data += chunk; }) collects response data.


• res.on("end", () => { console.log(data); }) logs the final response.

3. Handling Different Routes in the Server


You can define multiple routes to serve different responses.
Example: Routing Requests
const http = require("http");
const url = require("url");

const server = http.createServer((req, res) => {


const parsedUrl = url.parse(req.url, true);
const pathname = parsedUrl.pathname;

res.writeHead(200, { "Content-Type": "text/plain" });

if (pathname === "/about") {


res.end("Welcome to the About Page!");
} else if (pathname === "/contact") {
res.end("Contact us at contact@example.com");
} else {
res.end("Home Page");
}
});

server.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
• pathname === "/about" serves the About page.
• pathname === "/contact" serves the Contact page.
• Default response serves the Home page.

4. Making POST Requests from the Client


For handling form submissions or API requests, use req.on("data") to process incoming data.
Example: Sending a POST Request
const http = require("http");

const data = JSON.stringify({ name: "Sai", age: 25 });

const options = {
hostname: "localhost",
port: 3000,
path: "/submit",
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": data.length
}

33
Full Stack Development (MERN)-CS631PE Department of CSE

};

const req = http.request(options, res => {


let responseData = "";

res.on("data", chunk => {


responseData += chunk;
});

res.on("end", () => {
console.log("Response from server:", responseData);
});
});

req.write(data);
req.end();
• http.request(options, callback) sends a POST request.
• req.write(data) sends the request body.
• req.end() completes the request.

5. Using Express for Simplified HTTP Services


Instead of manually handling requests, Express.js makes routing easier.
Example: Express Server with Routes
const express = require("express");
const app = express();

app.use(express.json());

app.get("/", (req, res) => res.send("Home Page"));


app.get("/about", (req, res) => res.send("About Page"));
app.post("/submit", (req, res) => res.json({ message: "Form Submitted", data: req.body }));

app.listen(3000, () => console.log("Express server running on http://localhost:3000"));


• app.get("/about", (req, res) => res.send("About Page")) handles GET requests.
• app.post("/submit", (req, res) => res.json({ message: "Form Submitted", data:
req.body })) handles POST requests.

Using Additional Node.js Modules-Using the OS Module

The OS module in Node.js provides methods to interact with the operating system,
retrieve system information, and manage resources efficiently. Let’s break it down
with detailed explanations and examples.
1. Importing the OS Module
To use the OS module, you need to import it:
const os = require("os");

34
Full Stack Development (MERN)-CS631PE Department of CSE

2. Getting System Information


Check OS Platform
console.log("Platform:", os.platform());
Returns the operating system platform (win32, linux, darwin for macOS).
Check OS Release
console.log("OS Release:", os.release());
Returns the version of the operating system.
Check OS Type
console.log("OS Type:", os.type());
Returns the name of the operating system (Windows_NT, Linux, Darwin).
3. CPU Information
Get CPU Architecture
console.log("CPU Architecture:", os.arch());
Returns the CPU architecture (x64, arm, ia32).
Get CPU Details
console.log("CPU Info:", os.cpus());
Returns an array containing details about each CPU core.
4. Memory Management
Get Total Memory
console.log("Total Memory:", os.totalmem());
Returns the total system memory in bytes.
Get Free Memory
console.log("Free Memory:", os.freemem());
Returns the available memory in bytes.
5. Network Information
Get Hostname
console.log("Hostname:", os.hostname());
Returns the system’s hostname.
Get Network Interfaces
console.log("Network Interfaces:", os.networkInterfaces());
Returns details about network adapters.
6. System Uptime
Get System Uptime
console.log("System Uptime (seconds):", os.uptime());
Returns the system uptime in seconds.
7. User Information
Get Current User Info
console.log("User Info:", os.userInfo());
Returns details about the currently logged-in user.
8. Temporary Directory
Get OS Temporary Directory
console.log("Temp Directory:", os.tmpdir());
Returns the default directory for temporary files.

35
Full Stack Development (MERN)-CS631PE Department of CSE

UNIT-5
Introduction

Why Do We Need React?


React is a powerful front-end library developed by Facebook, designed to create
interactive, efficient, and reusable UI components for web applications. Let’s explore
why React is essential for modern web development.

1. Component-Based Architecture
React encourages the component-based approach, making UI development modular
and scalable.
• Instead of managing entire webpages, React allows breaking down UI into small
reusable components.
• Each component is independent, making debugging and maintenance easier.
Example: Creating a Component
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
<Greeting name="Sai" />
Here, Greeting is a reusable component that can be used multiple times.

2. Efficient DOM Manipulation (Virtual DOM)


Traditional JavaScript manipulates the Real DOM, which is slow when handling
frequent updates. React uses the Virtual DOM to optimize rendering.
• React compares the Virtual DOM with the previous state and updates only the
changed parts, improving performance.
• This technique reduces unnecessary rendering, leading to a smooth user experience.
Example: Updating State Efficiently
import { useState } from "react";

function Counter() {
const [count, setCount] = useState(0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Only the count updates, preventing unnecessary DOM manipulations.

3. Declarative UI
React’s declarative programming model simplifies UI logic.

36
Full Stack Development (MERN)-CS631PE Department of CSE

• Instead of manually managing UI updates, React describes how UI should look based
on data.
• It automatically updates components when data changes.
Example: Conditional Rendering
function UserStatus({ isLoggedIn }) {
return isLoggedIn ? <p>Welcome, Sai!</p> : <p>Please log in.</p>;
}
React automatically re-renders when isLoggedIn state changes.

4. One-Way Data Binding for Predictability


React follows one-way data binding, meaning data flows from parent to child
components.
• This approach ensures predictable behavior and better debugging.
• Reduces complexity compared to traditional two-way data binding used in
frameworks like Angular.
Example: Passing Data from Parent to Child
function Profile({ name }) {
return <p>User: {name}</p>;
}

<Profile name="Sai Kishore" />


The name is passed from the parent component, making data management clear and
structured.

5. React Hooks for State Management


React hooks eliminate the need for class components and allow handling state inside
functional components.
• useState(): Manages component state.
• useEffect(): Handles side effects like fetching data.
Example: Using useEffect() to Fetch Data
import { useState, useEffect } from "react";

function FetchData() {
const [data, setData] = useState([]);

useEffect(() => {
fetch("https://api.example.com/data")
.then(response => response.json())
.then(result => setData(result));
}, []);

return <p>Data: {JSON.stringify(data)}</p>;


}
The component fetches data when mounted, ensuring smooth dynamic updates.

37
Full Stack Development (MERN)-CS631PE Department of CSE

6. Seamless Integration with Backend Technologies


React easily integrates with backend APIs, databases, and other frameworks.
• Works well with Node.js, Express, and RESTful APIs.
• Can be paired with GraphQL for optimized data handling.
Example: Calling an API with React
fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(data => console.log(data));

7. Performance Optimization with React Fiber


React's Fiber architecture improves performance by handling UI updates efficiently.
• Supports concurrent rendering for smoother animations and transitions.
• Prioritizes user interactions and minimizes blocking tasks.

8. Strong Community & Ecosystem


React has a huge developer community, providing:
• Thousands of pre-built UI components.
• Extensive documentation and tutorials.
• Continuous updates with cutting-edge features.

Simple React Structure – Explained in Detail

React follows a component-based structure, allowing developers to build modular and


reusable UI elements efficiently. Let’s break down a simple React application step by step.

1. Basic Folder Structure


A typical React app includes the following files and directories:
my-app/
│── src/ # Main source code directory
│ │── components/ # Reusable components
│ │── App.js # Main app component
│ │── index.js # Entry file
│── public/ # Static assets (HTML, images)
│── package.json # Dependency management
│── node_modules/ # Installed packages

2. Entry Point (index.js)


The index.js file serves as the entry point, rendering the React app inside an HTML page.
Code in index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

38
Full Stack Development (MERN)-CS631PE Department of CSE

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
Explanation:
• ReactDOM.createRoot(document.getElementById("root")): Attaches React to the
HTML element with id "root".
• <App />: The main component that gets rendered.
The root element exists inside public/index.html:
<div id="root"></div>
React injects the entire app inside this div.

3. Main App Component (App.js)


The App.js file defines the root component.
Code in App.js
import React from "react";
import Greeting from "./components/Greeting"; // Import a custom component

function App() {
return (
<div>
<h1>Welcome to My React App</h1>
<Greeting name="Sai Kishore" /> {/* Using the Greeting component */}
</div>
);
}

export default App;


Explanation:
• import React from "react" → React must be imported in every component.
• function App() → A functional component returns JSX (HTML-like syntax).
• <Greeting name="Sai Kishore" /> → A reusable component is used inside App.js.

4. Creating a Reusable Component (Greeting.js)


Components are reusable UI elements.
Code in Greeting.js
import React from "react";

function Greeting(props) {
return <h2>Hello, {props.name}!</h2>;
}

export default Greeting;


Explanation:
• Props (props.name) → Props allow passing values dynamically.
• export default Greeting; → Makes the component available for import.

39
Full Stack Development (MERN)-CS631PE Department of CSE

5. Styling the Components


You can apply styles using CSS files, inline styles, or libraries.
Example: External CSS (App.css)
h1 {
color: blue;
font-family: Arial;
}
Import it inside App.js:
import "./App.css";

6. Running the Application


To start the React app, run:
npm start
This launches the development server at http://localhost:3000.

Understanding the Virtual DOM in React

The Virtual DOM is a key concept in React that enhances performance by efficiently updating
the UI without directly manipulating the actual Real DOM. Let's break it down step by step.

1. What is the Virtual DOM?


The Virtual DOM (VDOM) is a lightweight, in-memory representation of the actual DOM.
React uses this system to optimize UI updates.
Instead of updating the Real DOM directly, React first updates the Virtual DOM, compares
changes, and only updates the necessary parts.
This makes rendering faster and avoids unnecessary DOM manipulations.

2. Difference Between the Real DOM & Virtual DOM


Feature Real DOM Virtual DOM

Updates Slow, directly modifies the UI Fast, modifies an internal representation

Performance Less efficient Highly optimized

Re-rendering Entire DOM tree updates Only the changed components update

Usage Used by traditional browsers Used by React for optimization

3. How the Virtual DOM Works?


React follows a three-step process when updating the UI:
Step 1: Rendering the Virtual DOM
Whenever React components change, React creates a Virtual DOM tree representing the
updated UI.
Step 2: Diffing Algorithm (Comparing Changes)

40
Full Stack Development (MERN)-CS631PE Department of CSE

React compares the new Virtual DOM with the old one using a diffing algorithm.
Step 3: Efficiently Updating the Real DOM
Instead of updating the entire DOM, React replaces only the changed elements, minimizing
performance overhead.

4. Example: How React Updates the Virtual DOM


Let's consider a simple counter component:
import { useState } from "react";

function Counter() {
const [count, setCount] = useState(0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

export default Counter;


(How React Works Here)
Initial Render: React creates a Virtual DOM representation of the component.
State Update (count + 1) → React creates a new Virtual DOM reflecting the updated
state.
Diffing Algorithm: React compares changes in the Virtual DOM.
Efficient DOM Update: Instead of updating everything, React only updates the p element
where the count changes.
Result: Faster, efficient updates without modifying the entire DOM structure!

5. Why is the Virtual DOM Important?


• Optimized Rendering → Faster UI updates
• Less Re-rendering → Only affected components update
• Better Performance → Smooth user experience

The Virtual DOM is the backbone of Reacts efficiency, ensuring fast UI updates while
reducing browser workload. This makes React ideal for dynamic applications like
dashboards, social media, and e-commerce sites.

41
Full Stack Development (MERN)-CS631PE Department of CSE

Introducing React Components


React components are the building blocks of a React application. They are
independent, reusable pieces of UI that can be combined to create complex
interfaces.

1. What is a React Component?


A React component is a function or class that returns a piece of UI (written in JSX).
Components allow developers to break down an application into smaller, reusable
parts.
Types of Components:
• Functional Components (recommended) → Simple functions that return JSX.
• Class Components (legacy) → Uses ES6 classes to manage state & lifecycle.

2. Functional Component Example


import React from "react";

function Greeting() {
return <h1>Hello, Sai Kishore! Welcome to React!</h1>;
}

export default Greeting;


Explanation:
• function Greeting() → Defines a functional component.
• JSX (<h1>) → Returns UI elements.
• export default Greeting; → Makes it reusable.
Usage in Another Component (App.js)
import Greeting from "./Greeting";

function App() {
return (
<div>
<Greeting /> {/* Reusing Greeting component */}
</div>
);
}

export default App;

3. Class Component Example (Legacy)


import React, { Component } from "react";

class Welcome extends Component {

42
Full Stack Development (MERN)-CS631PE Department of CSE

render() {
return <h1>Welcome, {this.props.name}!</h1>;
}
}

export default Welcome;


Explanation:
• class Welcome extends Component → Creates a class-based component.
• this.props.name → Uses props for dynamic data.
Usage in Another Component
<Welcome name="Sai Kishore" />

4. Using Props in Components


Props allow data passing between components.
Example: Passing Data Using Props
function UserProfile(props) {
return <p>User: {props.name}, Age: {props.age}</p>;
}

<UserProfile name="Sai Kishore" age={25} />


Props are immutable → Components cannot modify their own props.

5. Using State in Components


State allows components to track changes and update the UI dynamically.
Example: Using useState Hook
import { useState } from "react";

function Counter() {
const [count, setCount] = useState(0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

export default Counter;


State changes trigger re-renders → React updates only the modified elements.

6. Combining Components
Multiple components can be combined into a larger UI structure.
Example: Nested Components

43
Full Stack Development (MERN)-CS631PE Department of CSE

function Header() {
return <h1>React App</h1>;
}

function Footer() {
return <footer>Copyright © 2025</footer>;
}

function App() {
return (
<div>
<Header />
<p>Main Content</p>
<Footer />
</div>
);
}

export default App;


Advantages of Components:
• Reusable → Use across multiple pages
• Maintainable → Organized code structure
• Dynamic → Works with props & state

Creating Components in React


In React, components are the building blocks of user interfaces. They allow you to
create reusable UI elements and maintain a clean, modular codebase.
1. Functional Components (Recommended)
Functional components are simple JavaScript functions that return JSX.
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}

export default Greeting;


Props (props.name) → Allow passing data dynamically.
Usage in App.js:

import Greeting from "./Greeting";

function App() {
return <Greeting name="Sai Kishore" />;
}

export default App;

44
Full Stack Development (MERN)-CS631PE Department of CSE

2. Class Components (Legacy)


Class components use the ES6 class syntax and manage state.
import React, { Component } from "react";

class Counter extends Component {


constructor(props) {
super(props);
this.state = { count: 0 };
}

render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}

export default Counter;


State (this.state.count) → Stores component-specific data.
Event Handling (setState) → Updates the UI dynamically.

Data Flow in React


React follows a unidirectional data flow, meaning data moves in a single direction:
from parent to child components.
1. Props for Parent-to-Child Data Passing
Props allow passing data from a parent to a child component.
Parent Component (App.js):
import Profile from "./Profile";

function App() {
return <Profile name="Sai Kishore" age={25} />;
}

export default App;


Child Component (Profile.js):
function Profile(props) {
return <p>User: {props.name}, Age: {props.age}</p>;
}

45
Full Stack Development (MERN)-CS631PE Department of CSE

export default Profile;


Props are immutable → Child components cannot modify them.

2. State for Local Data Handling


State allows components to manage internal data dynamically.
import { useState } from "react";

function Counter() {
const [count, setCount] = useState(0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

export default Counter;


State updates re-render the component automatically.

3. Lifting State Up for Child-to-Parent Communication


Sometimes, a child component needs to update the parent’s state.
Parent Component (App.js):
import { useState } from "react";
import Child from "./Child";

function App() {
const [message, setMessage] = useState("");

return (
<div>
<Child updateMessage={setMessage} />
<p>Message: {message}</p>
</div>
);
}

export default App;


Child Component (Child.js):
function Child({ updateMessage }) {
return <button onClick={() => updateMessage("Hello, Sai!")}>Send
Message</button>;

46
Full Stack Development (MERN)-CS631PE Department of CSE

export default Child;


The child modifies the parent’s state using a function prop.

Rendering and Life Cycle Methods in React – Detailed Explanation


React follows a component lifecycle, which consists of different phases where
components are created, updated, and destroyed. Understanding these lifecycle
methods and the rendering process helps optimize performance and debugging.

1. Rendering in React
Rendering in React is controlled by ReactDOM and occurs when: ✔ A component is
first mounted (initial render).
A component’s state or props change (re-render).
The parent component updates, affecting child components.

2. Initial Render (Mounting Phase)


When a component is first created, React follows these steps:
Example: Mounting a Functional Component
import React from "react";

function Greeting({ name }) {


return <h1>Hello, {name}!</h1>;
}

export default Greeting;


This component renders once when the app starts.
Example: Mounting a Class Component
import React, { Component } from "react";

class Welcome extends Component {


constructor(props) {
super(props);
console.log("Component is mounting...");
}

render() {
return <h1>Welcome, {this.props.name}!</h1>;
}
}

export default Welcome;


The constructor runs once, before rendering.

47
Full Stack Development (MERN)-CS631PE Department of CSE

3. Lifecycle Methods in Class Components


React provides lifecycle methods in class components to control behavior at different
stages.
Mounting Phase (Initial Render)
Method Purpose

constructor() Initializes state & props

render() Returns JSX to display UI

componentDidMount() Executes after the component is added to the DOM

Example of componentDidMount()
class DataFetcher extends Component {
constructor(props) {
super(props);
this.state = { data: null };
}

componentDidMount() {
fetch("https://api.example.com/data")
.then(res => res.json())
.then(result => this.setState({ data: result }));
}

render() {
return <p>Data: {JSON.stringify(this.state.data)}</p>;
}
}
componentDidMount() runs after the first render, making it ideal for fetching data.

4. Updating Phase (Re-rendering)


When state or props change, the component re-renders, triggering update lifecycle
methods.
Method Purpose

shouldComponentUpdate() Controls re-rendering

componentDidUpdate() Runs after re-rendering

render() Renders updated UI

Example: Updating State in a Counter


class Counter extends Component {
constructor(props) {

48
Full Stack Development (MERN)-CS631PE Department of CSE

super(props);
this.state = { count: 0 };
}

componentDidUpdate(prevProps, prevState) {
console.log(`Updated! Previous count: ${prevState.count}`);
}

increment = () => {
this.setState({ count: this.state.count + 1 });
};

render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
componentDidUpdate() runs after each state update.

5. Unmounting Phase (Component Removal)


When a component is removed from the DOM, React calls unmount lifecycle
methods.
Method Purpose

componentWillUnmount() Cleans up before removal

Example: Cleanup in componentWillUnmount()


class Timer extends Component {
componentWillUnmount() {
console.log("Component is unmounting...");
clearInterval(this.timer);
}

render() {
return <p>Timer running...</p>;
}
}
Used for cleaning event listeners, timers, and subscriptions.

6. Lifecycle Methods in Functional Components

49
Full Stack Development (MERN)-CS631PE Department of CSE

React hooks provide lifecycle behavior in functional components.


Using useEffect() for Lifecycle Control
import { useState, useEffect } from "react";

function Timer() {
const [time, setTime] = useState(0);

useEffect(() => {
const interval = setInterval(() => setTime(time + 1), 1000);

return () => clearInterval(interval); // Cleanup


}, [time]);

return <p>Time: {time} seconds</p>;


}
useEffect(() => {}, []) runs on mount.
Cleanup functions run before unmounting.

Working with Forms in React


Forms in React allow users to input and submit data, making applications interactive.
React provides controlled components to handle form inputs efficiently.

1. Controlled vs. Uncontrolled Components


React forms can be:
Controlled (recommended) → State manages input values.
Uncontrolled → Use traditional DOM methods (ref) instead.

2. Controlled Components (Recommended)


React controls the form state through useState().
Example: Handling Input in a Form
import { useState } from "react";

function SignupForm() {
const [username, setUsername] = useState("");

return (
<form>
<label>Username:</label>
<input type="text" value={username} onChange={(e) =>
setUsername(e.target.value)} />
<p>Entered: {username}</p>
</form>
);
}

50
Full Stack Development (MERN)-CS631PE Department of CSE

export default SignupForm;


State (username) holds input data.
onChange={(e) => setUsername(e.target.value)} updates state on every keystroke.

3. Handling Multiple Form Inputs


Instead of managing state separately for each field, use one state object.
Example: Managing Multiple Inputs
import { useState } from "react";

function UserForm() {
const [formData, setFormData] = useState({ name: "", email: "" });

const handleChange = (e) => {


setFormData({ ...formData, [e.target.name]: e.target.value });
};

return (
<form>
<input name="name" placeholder="Name" onChange={handleChange} />
<input name="email" type="email" placeholder="Email"
onChange={handleChange} />
<p>Name: {formData.name}, Email: {formData.email}</p>
</form>
);
}

export default UserForm;


Object state (formData) manages multiple inputs dynamically.

4. Handling Form Submission


Forms need to prevent default behavior and process user input.
Example: Submitting a Form
function SubmitForm() {
const [username, setUsername] = useState("");

const handleSubmit = (e) => {


e.preventDefault();
console.log("Submitted:", username);
};

return (
<form onSubmit={handleSubmit}>

51
Full Stack Development (MERN)-CS631PE Department of CSE

<input type="text" value={username} onChange={(e) =>


setUsername(e.target.value)} />
<button type="submit">Submit</button>
</form>
);
}

export default SubmitForm;


onSubmit={(e) => handleSubmit(e)} prevents default form submission.
console.log(username) logs user input.

5. Handling Checkboxes, Radio Buttons, and Select Dropdowns


Forms in React support various input types.
Checkbox Example
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false);

return (
<label>
<input type="checkbox" checked={isChecked} onChange={(e) =>
setIsChecked(e.target.checked)} />
Accept Terms & Conditions
</label>
);
}

export default CheckboxExample;


Radio Button Example
function GenderForm() {
const [gender, setGender] = useState("");

return (
<form>
<label>
<input type="radio" value="Male" name="gender" onChange={(e) =>
setGender(e.target.value)} />
Male
</label>
<label>
<input type="radio" value="Female" name="gender" onChange={(e) =>
setGender(e.target.value)} />
Female
</label>
<p>Selected Gender: {gender}</p>

52
Full Stack Development (MERN)-CS631PE Department of CSE

</form>
);
}

export default GenderForm;


Dropdown Example
function DropdownExample() {
const [selectedOption, setSelectedOption] = useState("");

return (
<select onChange={(e) => setSelectedOption(e.target.value)}>
<option value="">Choose an option</option>
<option value="React">React</option>
<option value="Node.js">Node.js</option>
</select>
);
}

export default DropdownExample;

6. Validation in Forms
React allows form validation before submission.
Example: Validating Input
function ValidateForm() {
const [email, setEmail] = useState("");
const [error, setError] = useState("");

const handleSubmit = (e) => {


e.preventDefault();
if (!email.includes("@")) {
setError("Invalid email!");
} else {
setError("");
console.log("Valid email:", email);
}
};

return (
<form onSubmit={handleSubmit}>
<input type="email" placeholder="Enter email" onChange={(e) =>
setEmail(e.target.value)} />
<button type="submit">Submit</button>
<p style={{ color: "red" }}>{error}</p>
</form>

53
Full Stack Development (MERN)-CS631PE Department of CSE

);
}

export default ValidateForm;

Routing in React
Routing in React allows users to navigate between different views or pages without
reloading the entire application. It is efficiently managed using the React Router library.

1. Why Do We Need Routing?


Single-page applications (SPAs) need multiple views without reloading.
Improves user experience by handling navigation smoothly.
Helps load dynamic content without losing state.

2. Installing React Router


To add routing functionality, install react-router-dom:
npm install react-router-dom

3. Basic Routing Setup


The following example demonstrates a simple routing setup.
App.js (Main Component)
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";

function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}

export default App;


<Router> → Defines the routing system.
<Routes> → Holds all the possible routes.
<Route path="/" element={<Home />}/> → Maps path / to the Home component.

54
Full Stack Development (MERN)-CS631PE Department of CSE

4. Creating Component Pages


Home.js
function Home() {
return <h1>Welcome to the Home Page!</h1>;
}

export default Home;


About.js
function About() {
return <h1>About Us Page</h1>;
}

export default About;

5. Adding Navigation Links


Use Link to navigate between pages.
Example: Navbar
import { Link } from "react-router-dom";

function Navbar() {
return (
<nav>
<Link to="/">Home</Link> | <Link to="/about">About</Link>
</nav>
);
}

export default Navbar;


<Link to="/about">About</Link> → Prevents full-page reload.
Uses client-side routing for a faster experience.

6. Handling 404 Pages


If an invalid URL is accessed, a fallback 404 page can be set.
Example: Adding a "Not Found" Route
function NotFound() {
return <h1>404 - Page Not Found</h1>;
}

<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NotFound />} /> {/* Handles unmatched routes */}
</Routes>

55
Full Stack Development (MERN)-CS631PE Department of CSE

7. Route Parameters for Dynamic Pages


Route parameters allow dynamic content based on the URL.
Example: Dynamic Profile Page
Route Setup (App.js)
<Route path="/profile/:username" element={<Profile />} />
Profile Component (Profile.js)
import { useParams } from "react-router-dom";

function Profile() {
const { username } = useParams();
return <h1>Welcome, {username}!</h1>;
}

export default Profile;

56

You might also like