UNIT-4 node js
UNIT-4 node js
UNIT-4 node js
Node.js: Getting Started with Node.js, Using Events, Listeners, Timers, and
Callbacks in Node.js, Handling Data I/O in Node.js. Accessing the File System
from Node.js, Implementing HTTP Services in Node.js.
Q) Differentiate React and Node
Development Ecosystem Large and active community Large and active community
This can be used to install, update, or uninstall any package through NPM.
1. Installing: npm install <package_name>[@<version>]
This will create a folder node_modules in the current directory and put all the
packages related files inside it. Here @version is optional if you don't specify
the version, the latest version of the module will be downloaded.
Best Practice: Start all projects with npm init. This will create a new
package.json for you which allows you to add a bunch of metadata to help
others working on the project have the same setup as you.
2. Update: We can also update the packages downloaded from the registry
to keep the code more secure and stable. Any update for a global
package can be done using the following command.
To create a package.json file, open the Node command prompt and type
the below command.
npm init
eg.
{
"name": "my-package",
"version": "1.0.0",
"description": "A simple Node.js package for performing basic math
operations.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"node",
"math",
"package"
],
"author": "Your Name",
"license": "MIT"
}
A module can contain functions, classes, objects, or any other piece of code
that can be shared between different parts of an application.
Node.js has a built-in module system that allows you to create and use
modules. A module can be defined in a separate file, and can be loaded into
other parts of the application using the require() function.
Eg.
calc.js:
exports.add = (a, b) => {
console.log("Add Result:", a + b);
};
demo.js:
const myCalculator = require("./calc");
myCalculator.add(1, 2);
myCalculator.subtract(3, 2);
Here, the functions are exported using exports object in calc.js and require()
function is used in demo.js which loads the module calc.
Output:
D:\PVP\MWA\Lab\NodeDemo> node demo.js
Add Result: 3
Sub Result: 1
Node is used to build the back-end of web applications and provides an event-
driven, non-blocking I/O model that makes it highly efficient for handling
large amounts of data.
The Node.js event model does things differently from traditional event
model. Instead of executing all the work for each request on individual
threads, work is added to an event queue and then picked up by a single
thread running an event loop. The event loop grabs the top item in the event
queue, executes it, and then grabs the next item. When executing code that
is no longer live or has blocking I/O, instead of calling the function directly,
the function is added to the event queue along with a callback that is executed
after the function completes. When all events on the Node.js event queue have
been executed, the Node application terminates.
• Make a call to one of the blocking I/O library calls such as writing to a
file or connecting to a database.
• Add a built-in event listener to a built-in event such as an http.request
or server.connection.
• Create own event emitters and add custom listeners to them.
• Use the process.nextTick option to schedule work to be picked up on
the next cycle of the event loop.
• Use timers to schedule work to be done after a particular amount of
time or at periodic intervals.
Eg. Create any custom event as an example.
The setTimeout() function returns a timer object ID. You can pass this ID to
clearTimeout(timeoutId) at any time before the delayMilliSeconds expires to
cancel the timeout function.
Timer1.js
function simpleTimeout(consoleTimer){
console.timeEnd(consoleTimer);
}
console.time("twoSecond");
setTimeout(simpleTimeout, 2000, "twoSecond");
console.time("oneSecond");
setTimeout(simpleTimeout, 1000, "oneSecond");
console.time("fiveSecond");
setTimeout(simpleTimeout, 5000, "fiveSecond");
console.time("50MilliSecond");
setTimeout(simpleTimeout, 50, "50MilliSecond");
• The console.time() method starts a timer you can use to track how
long an operation takes. You give each timer a unique name, and may
have up to 10,000 timers running on a given page.
• When you call console.timeEnd() with the same name, the browser will
output the time, in milliseconds, that elapsed since the timer was
started.
Output:
C:\Program Files\nodejs\node.exe .\Timer1.js
50MilliSecond: 50.341064453125 ms
50MilliSecond: 50.751ms
oneSecond: 1015.48388671875 ms
oneSecond: 1.016s
twoSecond: 2014.297119140625 ms
twoSecond: 2.014s
fiveSecond: 5008.2470703125 ms
fiveSecond: 5.009s
Eg. Timer2.js
function updateX(){
x += 1;
}
function updateY(){
y += 1;
}
function updateZ(){
z += 1;
displayValues();
}
setInterval(updateX, 500);
setInterval(updateY, 1000);
setInterval(updateZ, 2000);
Output:
C:\Program Files\nodejs\node.exe .\Timer2.js
X=3; Y=1; Z=1
X=7; Y=3; Z=2
X=11; Y=5; Z=3
X=15; Y=7; Z=4
X=19; Y=9; Z=5
X=23; Y=11; Z=6
X=27; Y=13; Z=7
Eg. Timer3.js
var fs = require("fs");
fs.stat("nexttick.js", function(){
console.log("nexttick.js Exists");
});
setImmediate(function(){
console.log("Immediate Timer 1 Executed");
});
setImmediate(function(){
console.log("Immediate Timer 2 Executed");
});
process.nextTick(function(){
console.log("Next Tick 1 Executed");
});
process.nextTick(function(){
console.log("Next Tick 2 Executed");
});
Output:
C:\Program Files\nodejs\node.exe .\Timer3.js
Next Tick 1 Executed
Next Tick 2 Executed
Immediate Timer 1 Executed
Immediate Timer 2 Executed
nexttick.js Exists
If for some reason later do not want the program to terminate if the
interval function is the only event left on the queue, you can use the
ref() function to rereference it: myInterval.ref();
Event listeners are functions that are registered to listen for and
respond to specific events. When an event occurs, all registered event listeners
for that event are executed in the order they were registered. Event listeners
can be added or removed dynamically, and multiple event listeners can be
registered for the same event.
Events are emitted using an EventEmitter object. This object is included
in the events module. The emit(eventName, [args]) function triggers the
eventName event and includes any arguments provided.
The following code snippet shows how to implement a simple event emitter:
var events = require('events');
var emitter = new events.EventEmitter();
emitter.emit("simpleEvent");
Eg. 1:
Output:
node Event_Demo.js
Welcome to pvpsit
Good bye to pvpsit
2 Listner(s) listening to greet event
listener bye removed..
Eg. 2.
Event1.js
this.withdraw = function(amount){
this.balance -= amount;
this.emit('balanceChanged');
};
}
Account.prototype.__proto__ = events.EventEmitter.prototype;
function displayBalance(){
console.log("Account balance: $%d", this.balance);
}
function checkOverdraw(){
if (this.balance < 0){
console.log("Account overdrawn!!!");
}
}
Output:
C:\Program Files\nodejs\node.exe .\Event1.js
Account balance: $220
Account balance: $540
Account balance: $1140
Goal Achieved!!!
Account balance: $-60
Account overdrawn!!!
function logResult() {
console.log('The sum is:');
}
sum(2, 3, logResult);
Output:
node callback0.js
The sum is:
5
Callback with parameters:
Eg. 1:
function add(a, b, callback) {
let result = a + b;
callback(result);
}
function logResult(sum) {
console.log('The sum is %d',sum);
}
add(2, 3, logResult);
Output:
node callback1.0.js
The sum is 5
Eg. 2:
var events = require('events');
function CarShow() {
events.EventEmitter.call(this);
this.seeCar = function(make){
this.emit('sawCar', make);
};
}
CarShow.prototype.__proto__ = events.EventEmitter.prototype;
Eg. 1:
function counter() {
let count = 0;
return incrementCount;
}
Output:
node callback2.0.js
Count is now 1
Count is now 2
Eg.2:
Output:
node callback2.js
Normal Callback: Saw a Bugatti
Normal Callback: Saw a Bugatti
Normal Callback: Saw a Bugatti
Closure Callback: Saw a Ferrari
Closure Callback: Saw a Porsche
Closure Callback: Saw a Bugatti
The second loop also iterates over the cars array, but it uses a closure
to pass the log message to the callback function.
function logResult(result) {
console.log(`The final result is ${result}`);
}
add(2, 3, function(sum) {
square(sum, function(result) {
logResult(result);
});
});
Output:
node callback3.0.js
The final result is 25
Eg. 2:
function logCar(car, callback){
console.log("Saw a %s", car);
if(cars.length){
process.nextTick(function(){
callback();
});
}
}
function logCars(cars){
var car = cars.pop();
logCar(car, function(){
logCars(cars);
});
}
var cars = ["Ferrari", "Porsche", "Bugatti",
"Lamborghini", "Aston Martin"];
logCars(cars);
Output:
node callback3.js
Saw a Aston Martin
Saw a Lamborghini
Saw a Bugatti
Saw a Porsche
Saw a Ferrari
Node provides Buffer class which provides instances to store raw data
similar to an array of integers but corresponds to a raw memory allocation
outside the V8 heap. Buffer class is a global class that can be accessed in an
application without importing the buffer module.
var buf1 = new Buffer(100);
var buf2 = new Buffer(100);
O/P:
PS D:\PVP\MWA\Lab\Files> node Event_Demo.js
Welcome to pvpsit
Good bye to pvpsit
2 Listner(s) listening to greet event
listener bye removed..
PS D:\PVP\MWA\Lab\Files>
* History restored
buffer 3:abcdefghijklmnopqrstuvwxyz
buf1 Octets written : 17
buffer 1:Welcome to pvpsit
buf2 Octets written : 13
buffer 2:Welcome to it
buffer after concatinating buf1 and buf2: Welcome to pvpsitWelcome to it
buffer4 content: abcdefghijklmnopqrstuvwxyz
buf4.slice(0,9): abcdefghi and length is 9
abcdefghijklmnopqrstuvwxyz comes after abcdefghi
{
type: 'Buffer',
data: [
97, 98, 99, 100,
101, 102, 103, 104,
105
]
}
Writing to Buffers Syntax Following is the syntax of the method to write into
a Node Buffer: buf.write(string[, offset][, length][, encoding])
Parameters Here is the description of the parameters used: • string - This is
the string data to be written to buffer.
• offset - This is the index of the buffer to start writing at. Default value is 0.
• length - This is the number of bytes to write. Defaults to buffer.length.
• encoding - Encoding to use. 'utf8' is the default encoding.
Return Value This method returns the number of octets written. If there is
not enough space in the buffer to fit the entire string, it will write a part of
the string.
Reading from Buffers Syntax Following is the syntax of the method to read
data from a Node Buffer: buf.toString([encoding][, start][, end])
Parameters Here is the description of the parameters used:
• encoding - Encoding to use. 'utf8' is the default encoding.
• start - Beginning index to start reading, defaults to 0.
• end - End index to end reading, defaults is complete buffer.
Return Value This method decodes and returns a string from buffer data
encoded using the specified character set encoding.
Convert Bufferto JSON Syntax Following is the syntax of the method to
convert a Node Buffer into JSON object:
buf.toJSON()
Return Value This method returns a JSON-representation of the Buffer
instance.
Copy Buffer Syntax Following is the syntax of the method to copy a node
buffer: buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])
Parameters Here is the description of the parameters used:
• targetBuffer - Buffer object where buffer will be copied.
• targetStart - Number, Optional, Default: 0
• sourceStart - Number, Optional, Default: 0
• sourceEnd - Number, Optional, Default: buffer.length
Return Value No return value.
Slice Buffer Syntax Following is the syntax of the method to get a sub-
buffer of a node buffer: buf.slice([start][, end])
Parameters Here is the description of the parameters used:
• start - Number, Optional, Default: 0
• end - Number, Optional, Default: buffer.length
Return Value Returns a new buffer which references the same memory as
the old one
Buffer Length Syntax Following is the syntax of the method to get a size of
a node buffer in bytes: buf.length;
Return Value Returns the size of a buffer in bytes.
Streams are objects that let you read data from a source or write data to a
destination in continuous fashion. In Node.js, there are four types of
streams:
• Readable - Stream which is used for read operation.
• Writable - Stream which is used for write operation.
• Duplex - Stream which can be used for both read and write operation.
fileWriteStream.on("close", function(){
console.log("File Closed.");
});
while (grains.length){
var data = grains.pop() + " ";
fileWriteStream.write(data);
console.log("Wrote: %s", data);
}
fileWriteStream.end();
fileReadStream.on('data', function(chunk) {
console.log('Grains: %s', chunk);
console.log('Read %d bytes of data.', chunk.length);
});
console.log("File Compressed.");
fs.createReadStream('c.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('c.txt'));
console.log("File Decompressed.");
Q) Write a program in Node.js to count no.of lines, words and
characters in a given file.
const fs = require('fs');
// Listen for 'data' event, which is emitted whenever data is read from the
stream
stream.on('data', (data) => {
// Count lines by counting the number of newline characters
lines += data.split('\n').length;
// Listen for 'end' event, which is emitted when the end of the stream is
reached
stream.on('end', () => {
console.log(`Number of lines: ${lines}`);
console.log(`Number of words: ${words}`);
console.log(`Number of characters: ${chars}`);
});
function countChars(filename) {
const vowels = 'aeiouAEIOU';
let vowelCount = 0;
let consonantCount = 0;
let digitCount = 0;
let specialCharCount = 0;
stream.on('end', () => {
console.log(`Vowels: ${vowelCount}`);
console.log(`Consonants: ${consonantCount}`);
console.log(`Digits: ${digitCount}`);
console.log(`Special Characters: ${specialCharCount}`);
});
The Node File System (fs) module can be imported using the following
syntax:
var fs = require("fs")
Synchronous vs Asynchronous
Every method in the fs module has synchronous as well as asynchronous
forms.
Asynchronous methods take the last parameter as the completion function
callback and the first parameter of the callback function as error.
It is better to use an asynchronous method instead of a synchronous
method, as the former never blocks a program during its execution, whereas
the second one does.
Eg. Asynchronous read and write:
var fs = require('fs');
var fruitBowl = ['apple', 'orange', 'banana', 'grapes'];
function writeFruit(fd){
if (fruitBowl.length){
var fruit = fruitBowl.pop() + " ";
fs.write(fd, fruit, null, null, function(err, bytes){
if (err){
console.log("File Write Failed.");
} else {
console.log("Wrote: %s %dbytes", fruit, bytes);
writeFruit(fd);
}
});
} else {
fs.close(fd);
}
}
fs.open('fruit.txt', 'w', function(err, fd){
writeFruit(fd);
});
fd = fs.openSync('veggie.txt', 'r');
var veggies = "";
do {
var buf = new Buffer(5);
buf.fill();
var bytes = fs.readSync(fd, buf, null, 5);
console.log("read %dbytes", bytes);
veggies += buf.toString();
} while (bytes > 0);
fs.closeSync(fd);
console.log("Veg g (to get output shown) ies: " + veggies);
Q) Write a program in Node.js to access file system
A. accessing file statistics
var fs = require('fs');
fs.stat('file_stats.js', function (err, stats) {
if (!err){
console.log('stats: ' + JSON.stringify(stats, null, ' '));
console.log(stats.isFile() ? "Is a File" : "Is not a File");
console.log(stats.isDirectory() ? "Is a Folder" : "Is not a Folder");
console.log(stats.isSocket() ? "Is a Socket" : "Is not a Socket");
console.log(stats.isDirectory() ? "Is a Directory" : "Is not a Directory");
stats.isBlockDevice();
stats.isCharacterDevice();
stats.isSymbolicLink(); //only lstat
stats.isFIFO();
}
});
b. To list files/directories in a given directory:
var fs = require('fs');
var Path = require('path');
function WalkDirs(dirPath){
console.log(dirPath);
fs.readdir(dirPath, function(err, entries){
for (var idx in entries){
var fullPath = Path.join(dirPath, entries[idx]);
(function(fullPath){
fs.stat(fullPath, function (err, stats){
if (stats.isFile()){
console.log(fullPath);
} else if (stats.isDirectory()){
WalkDirs(fullPath);
}
});
})(fullPath);
}
});
}
WalkDirs("../Files");
C. To create a directory:
let fs = require('fs')
fs.mkdir("../Files/folderA", function(err){
console.log(err ? "Directory not created" : "Directory created.");
});
D. Listing Files:
fs.readdir(path, callback)
fs.readdirSync(path)
e. Deleting Files:
fs.unlink(path, callback)
fs.unlinkSync(path)
eg.
fs.unlink("new.txt", function(err){
console.log(err ? "File Delete Failed" : "File Deleted");
});
F. Truncating Files:
To truncate a file, use one the following fs calls and pass in the number of
bytes you want the file to contain when the truncation completes:
fs.truncate(path, len, callback)
fs.truncateSync(path, len)
The truncateSync(path) returns true or false based on whether the file is
successfully truncated. The asynchronous truncate() call passes an error
value to the callback function if an error is encountered when truncating the
file.
Eg.
fs.truncate("new.txt", function(err){
console.log(err ? "File Truncate Failed" : "File Truncated");
});
H. Delete Directories:
fs.rmdir(path, callback)
fs.rmdirSync(path)
eg.
let fs = require('fs')
fs.rmdir("../Files/folderA", function(err){
console.log(err ? "Directory not deleted": "Directory deleted.");
});
I. Renaming Files and Directories:
The oldPath specifies the existing file or directory path, and the newPath
specifies the new name. The renameSync(path) returns true or false based
on whether the file or directory is successfully renamed. The asynchronous
rename() call passes an error value to the callback function if an error is
encountered when renaming the file or directory.
Eg.
fs.rename("old.txt", "new.txt", function(err){ console.log(err ? "Rename Failed"
: "File Renamed"); });
When a file change occurs, the callback function is executed and passes a
current and previous Stats object.
Eg.
fs.watchFile("log.txt", {persistent:true, interval:5000}, function (curr, prev) {
console.log("log.txt modified at: " + curr.mtime); console.log("Previous
modification was: " + prev.mtime);
});
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Greeting Form</title>
</head>
<body>
<form action="/greet" method="POST">
<label for="name">Enter your name:</label>
<input type="text" id="name" name="name">
<button type="submit">Submit</button>
</form>
</body>
</html>
index.js
const http = require('http');
const fs = require('fs');
const path = require('path');
res.setHeader('Content-Type', 'text/plain');
res.statusCode = 200;
res.end(greeting);
});
} else {
res.statusCode = 404;
res.end('Not Found');
}
});
O/P:
node index.js
Server listening on port 3000