CS204 Unit4 Notes
CS204 Unit4 Notes
Node.js Introduction:
Node.js applications are written in JavaScript, and can be run within the
Node.js runtime on mac OS X, Microsoft Windows, and Linux.
You need to know that NodeJS isn’t a framework, and it’s not a
programing language.
Node.js lets developers use JavaScript to write command line tools and for
server-side scripting—running scripts server-side to produce dynamic web
page content before the page is sent to the user's web browser.
➢ When you create websites with PHP for example, you associate the
language with an HTTP web server such as Apache or Nginx. Each of
them has its own role in the process:
➢ Apache manages HTTP requests to connect to the server. Its role is more
or less to manage the in/out traffic.
➢ PHP runs the .php file code and sends the result to Apache, which then
sends it to the visitor.
➢ As several visitors can request a page from the server at the same time,
Apache is responsible for spreading them out and running
different threads at the same time.
➢ Each thread uses a different processor on the server (or a processor core)
A common task for a web server can be to open a file on the server and
return the content to the client.
Features of Node.js
Following are some of the important features that make Node.js the first choice
of software architects.
• Asynchronous and Event Driven − All APIs of Node.js library are
asynchronous, that is, non-blocking. It essentially means a Node.js based
server never waits for an API to return data. The server moves to the
next API after calling it and a notification mechanism of Events of
Node.js helps the server to get a response from the previous API call.
• Very Fast − Being built on Google Chrome's V8 JavaScript Engine,
Node.js library is very fast in code execution.
• Single Threaded but Highly Scalable − Node.js uses a single threaded
model with event looping. Event mechanism helps the server to respond
in a non-blocking way and makes the server highly scalable as opposed
to traditional servers which create limited threads to handle requests.
Node.js uses a single threaded program and the same program can
provide service to a much larger number of requests than traditional
servers like Apache HTTP Server.
• No Buffering − Node.js applications never buffer any data. These
applications simply output the data in chunks.
• License − Node.js is released under the MIT license
Following are the areas where Node.js is proving itself as a perfect technology
partner.
Node.js process model increases the performance and scalability with a few
caveats. Node.js is not fit for an application which performs CPU-intensive
operations like image processing or other heavy computation work because it
takes time to process a request and thereby blocks the single thread.
Unlike Apache, Node.js is monothread. This means that there is only one
process and one version of the program that can be used at any one time in its
memory.
V8 JavaScript Engine
Chrome needs to run some Javascript for a particular Web page, it doesn't run
the JavaScript itself. It uses the V8 engine to get that done so it passes the
code to V8 and it gets the results back. Same case with Node also to run a
Javascript code.
V8 is written in C++ . Chrome and Node are largely written in C++ because
they both provide bindings when they're instantiating the V8 engine.
This facilitates to create their own JavaScript runtime with interesting and
novel features.
Example Instance:
Chrome to interact with the DOM when the DOM isn't part of JavaScript.
Node to interact with file system when the file system isn't part of JavaScript
NodeJS Success Stories:
Callbacks:
Callback is an asynchronous equivalent for a function. A callback function is
called at the completion of a given task. Node makes heavy use of callbacks.
All the APIs of Node are written in such a way that they support callbacks.
For example, a function to read a file may start reading file and return the
control to the execution environment immediately so that the next instruction
can be executed. Once file I/O is complete, it will call the callback function
while passing the callback function, the content of the file as a parameter. So
there is no blocking or wait for File I/O. This makes Node.js highly scalable, as
it can process a high number of requests without waiting for any function to
return results.
These two examples explain the concept of blocking and non-blocking calls.
• The first example shows that the program blocks until it reads the file
and then only it proceeds to end the program.
• The second example shows that the program does not wait for file
reading and proceeds to print "Start here" and at the same time, the
program without blocking continues reading the file.
Thus, a blocking program executes very much in sequence. From the
programming point of view, it is easier to implement the logic but non-
blocking programs do not execute in sequence. In case a program needs to use
any data to be processed, it should be kept within the same block to make it
sequential execution.
Installation of Node.js on Windows
You have to follow the following steps to install the Node.js on your Windows:
The first step to install Node.js on windows is to download the installer. Visit the
official Node.js website i.e) https://nodejs.org/en/download/ and download the
.msi file according to your system environment (32-bit & 64-bit). An MSI
installer will be downloaded on your system.
NOTE :
To check that node.js was completely installed on your system or not, you can
run the following command in your command prompt or Windows Powershell
and test it:-
C:\Users\Admin> node -v
If node.js was completely installed on your system, the command prompt will
print the version of the node.js installed.
The final step in node.js installed is the updation of your local npm version(if
required) – the package manager that comes bundled with Node.js.
You can run the following command, to quickly update the npm
It allows the creation of scalable Web servers without threading and networking
tools using JavaScript and a collection of “modules” that handle various core
functionalities.
• Boolean
• Undefined
• Null
• String
• Number
Loose Typing: Node.js supports loose typing, it means you don’t need to specify
what type of information will be stored in a variable in advance. We use var
keyword in Node.js to declare any type of variable. Examples are given below:
Example:
// Variable store number data type
var a = 35;
console.log(typeof a);
Example:
var company = {
Name: "PES University",
Address: "India",
Contact: "+919876543210",
Email: "www.pes.edu"
};
Functions:
Node.js functions are defined using function keyword then the name of the
function and parameters which are passed in the function.
In Node.js, we don’t have to specify datatypes for the parameters and check the
number of arguments received.
Node.js functions follow every rule which is there while writing JavaScript
functions.
function multiply(num1, num2) {
// Declare variable
var x = 2;
var y = 3;
If you observe in the above example, we have created a function called “multiply”
with parameters same like JavaScript.
• Search the node.js command prompt in the search bar and open the node.js
command prompt.
• Go to the folder using cd command in command prompt and write the
following command node web.js
Now the server has started and go to the browser and open this url localhost:5000
NODE Modules
NPM Package
NPM is a package manager for Node.js packages, or modules if you like.
www.npmjs.com hosts thousands of free packages to download and use.
The NPM program is installed on your computer when you install Node.js
A package in Node.js contains all the files you need for a module.
Modules are JavaScript libraries you can include in your project.
Example:
validator package is downloaded and installed. NPM creates a folder named
"node_modules", where the package will be placed.
To include a module, use the require() function with the name of the module
•
Node JS Built-in Modules
➢ Node.js has many built-in modules that are part of the platform and comes
with Node.js installation.
➢ These modules can be loaded into the program by using the require
function.
➢ Syntax:
➢ var module = require('module_name');
➢ The require() function will return a JavaScript type depending on what the
particular module returns.
Core Modules Description
Some Modules which are Globally Available where there is no need of Require
() function
Ex: Console
Timer Module
Node JS Timer Module
• This module provides a way for functions to be called later at a given time.
• The Timer object is a global object in Node.js, and it is not necessary to
import it
Method Description
Ex:
function printHello() {
console.log( "Hello, World!");
}
// Now call above function after 2 seconds
var timeoutObj = setTimeout(printHello, 2000);
Some More examples of Local Modules:
1.Exporting Date Module
Date.js
exports.myDateTime=function(){
return Date()
};
Main Program where we are importing Date
var D=require(‘./Date.js’)
console.log(D.myDateTime());
2.
LOG.JS
var log = {
info: function (info) {
console.log('Info: ' + info);
},
warning:function (warning) {
console.log('Warning: ' + warning);
},
error:function (error) {
console.log('Error: ' + error);
}
};
module.exports = log
In the above example of logging module, we have created an object with three
functions - info(), warning() and error(). At the end, we have assigned this object
to module.exports. The module.exports in the above example exposes a log object
as a module.
myLogModule.info('Node.js started');
In the above example, app.js is using log module. First, it loads the logging
module using require() function and specified path where logging module is
stored. Logging module is contained in Log.js file in the root folder. So, we have
specified the path './Log.js' in the require() function. The '.' denotes a root folder.
The require() function returns a log object because logging module exposes an
object in Log.js using module.exports. So now you can use logging module as
an object and call any of its function using dot notation e.g myLogModule.info()
or myLogModule.warning() or myLogModule.error()
3.
Local.js
const welcome = {
sayHello : function() {
console.log("Hello user");
},
currTime : new Date().toLocaleDateString(),
companyName : "PESU"
}
Main.js
var local = require("./Welcome.js");
local.sayHello();
console.log(local.currTime);
console.log(local.companyName);
module.exports = welcome
- https://nodejs.org/api/fs.html, https://nodejs.org/api/querystring.html
The fs module provides a lot of very useful functionality to access and interact
with the file system.
There is no need to install it. Being part of the Node.js core, it can be used by
simply requiring it:
const fs = require('fs')
Common use for the File System module:
Read files
Create files
Update files
Delete files
Rename files
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.
What is Synchronous and Asynchronous approach?
Synchronous approach: They are called blocking functions as it waits for each
operation to complete, only after that, it executes the next operation, hence
blocking the next command from execution i.e. a command will not be executed
until & unless the query has finished executing to get all the result from
previous commands.
Asynchronous approach:
They are called non-blocking functions as it never waits for each operation to
complete, rather it executes all operations in the first go itself.
The result of each operation will be handled once the result is available i.e.
each command will be executed soon after the execution of the previous
command.
While the previous command runs in the background and loads the result once
it is finished processing the data.
Example:
Synchronous:
var fs = require("fs");
// Synchronous read
var data = fs.readFileSync('input.txt');
console.log("Synchronous read: " + data.toString());
Asynchronous:
var fs = require("fs");
// Asynchronous read
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("Asynchronous read: " + data.toString());
});
Once you do so, you have access to all its methods, which include:
• fs.access(): check if the file exists and Node.js can access it with its
permissions
• fs.appendFile(): append data to a file. If the file does not exist, it's created
• fs.chmod(): change the permissions of a file specified by the filename
passed. Related: fs.lchmod(), fs.fchmod()
• fs.chown(): change the owner and group of a file specified by the
filename passed. Related: fs.fchown(), fs.lchown()
• fs.close(): close a file descriptor
• fs.copyFile(): copies a file
• fs.createReadStream(): create a readable file stream
• fs.createWriteStream(): create a writable file stream
• fs.link(): create a new hard link to a file
• fs.mkdir(): create a new folder
• fs.mkdtemp(): create a temporary directory
• fs.open(): set the file mode
• fs.readdir(): read the contents of a directory
• fs.readFile(): read the content of a file. Related: fs.read()
• fs.readlink(): read the value of a symbolic link
• fs.realpath(): resolve relative file path pointers (., ..) to the full path
• fs.rename(): rename a file or folder
• fs.rmdir(): remove a folder
• fs.stat(): returns the status of the file identified by the filename passed.
Related: fs.fstat(), fs.lstat()
• fs.symlink(): create a new symbolic link to a file
• fs.truncate(): truncate to the specified length the file identified by the
filename passed. Related: fs.ftruncate()
• fs.unlink(): remove a file or a symbolic link
• fs.unwatchFile(): stop watching for changes on a file
• fs.utimes(): change the timestamp of the file identified by the filename
passed. Related: fs.futimes()
• fs.watchFile(): start watching for changes on a file. Related: fs.watch()
• fs.writeFile(): write data to a file. Related: fs.write()
One peculiar thing about the fs module is that all the methods are asynchronous
by default, but they can also work synchronously by appending Sync.
For example:
• fs.rename()
• fs.renameSync()
• fs.write()
• fs.writeSync()
1 r
Open file for reading. An exception occurs if the file does not exist.
2 r+
Open file for reading and writing. An exception occurs if the file does
not exist.
3 rs
Open file for reading in synchronous mode.
4 rs+
Open file for reading and writing, asking the OS to open it
synchronously. See notes for 'rs' about using this with caution.
5 w
Open file for writing. The file is created (if it does not exist) or truncated
(if it exists).
6 wx
Like 'w' but fails if the path exists.
7 w+
Open file for reading and writing. The file is created (if it does not exist)
or truncated (if it exists).
8 wx+
Like 'w+' but fails if path exists.
9 a
Open file for appending. The file is created if it does not exist.
10 ax
Like 'a' but fails if the path exists.
11 a+
Open file for reading and appending. The file is created if it does not
exist.
12 ax+
Like 'a+' but fails if the the path exists.
Writing a File
Syntax
Following is the syntax of one of the methods to write into a file −
fs.writeFile(filename, data[, options], callback)
This method will over-write the file if the file already exists. If you want to
write into an existing file then you should use another method available.
Parameters
Here is the description of the parameters used −
• path − This is the string having the file name including path.
• data − This is the String or Buffer to be written into the file.
• options − The third parameter is an object which will hold {encoding,
mode, flag}. By default. encoding is utf8, mode is octal value 0666. and
flag is 'w'
• callback − This is the callback function which gets a single parameter err
that returns an error in case of any writing error.
Reading a File
• Node implements File I/O using simple wrappers around standard POSIX
functions.
• The Node File System (fs) module can be imported using the following
syntax −
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.
Syntax
Following is the syntax of one of the methods to read from a file −
fs.read(fd, buffer, offset, length, position, callback)
This method will use file descriptor to read the file. If you want to read the file
directly using the file name, then you should use another method available.
Parameters
Here is the description of the parameters used −
• fd − This is the file descriptor returned by fs.open().
• buffer − This is the buffer that the data will be written to.
• offset − This is the offset in the buffer to start writing at.
• length − This is an integer specifying the number of bytes to read.
• position − This is an integer specifying where to begin reading from in
the file. If position is null, data will be read from the current file
position.
• callback − This is the callback function which gets the three arguments,
(err, bytesRead, buffer).
Closing a File
Syntax
Following is the syntax to close an opened file −
fs.close(fd, callback)
Parameters
Here is the description of the parameters used −
• fd − This is the file descriptor returned by file fs.open() method.
• callback − This is the callback function No arguments other than a
possible exception are given to the completion callback.
Truncate a File
Syntax
Following is the syntax of the method to truncate an opened file −
fs.ftruncate(fd, len, callback)
Parameters
Here is the description of the parameters used −
• fd − This is the file descriptor returned by fs.open().
• len − This is the length of the file after which the file will be truncated.
• callback − This is the callback function No arguments other than a
possible exception are given to the completion callback.
Delete a File
Syntax
Following is the syntax of the method to delete a file −
fs.unlink(path, callback)
Parameters
Here is the description of the parameters used −
• path − This is the file name including path.
• callback − This is the callback function No arguments other than a
possible exception are given to the completion callback.
URL Module:
As nodejs.org suggests:
The URL module provides utilities for URL resolution and parsing. It can be
accessed using:
Url module is one of the core modules that comes with node.js, which is used to
parse the URL and its other properties.
As you can see in the above screen, there are various properties used for URL
module.
//////////////////////////////////////////////////////////////////
Opening a file:
////////////////////////////////////////////////////////////////////////
var fs = require("fs");
// Asynchronous - Opening File
console.log("Going to open file!");
fs.open('input.txt', 'r+', function(err, data) {
if (err) {
return console.error(err);
}
console.log(data);
console.log("File opened successfully!");
});
////////////////////////////////////////////////////////////////////////
Reading from file:
////////////////////////////////////////////////////////////////////////
var fs = require('fs');
console.log(data.toString());
});
var fs = require('fs');
//////////////////////////////////////////////////////////////////////////////////////
Writing a file:
////////////////////////////////////////////////////////////////////////
var fs = require("fs");
///////////////////////////////////////////////////////////////////////
Reading from a file
///////////////////////////////////////////////////////////////////////
var fs = require('fs');
if (err) {
return console.error(err);
}
///////////////////////////////////////////////////////////////////////////
Delete a file
//////////////////////////////////////////////////////////////////////////
var fs = require('fs');
fs.unlink('data.txt', function () {
});
HTTP Module
Node.js has a built-in module called HTTP, which allows Node.js to transfer data over
the Hyper Text Transfer Protocol (HTTP).
To process HTTP requests in JavaScript and Node.js, we can use the built-in http
module. This core module is key in leveraging Node.js networking and is extremely
useful in creating HTTP servers and processing HTTP requests.
The http module comes with various methods that are useful when engaging with
HTTP network requests. One of the most commonly used methods within the http
module is the .createServer() method. This method is responsible for doing exactly
what its namesake implies; it creates an HTTP server. To implement this method to
create a server, the following code can be used:
server.listen(8080, () => {
const { address, port } = server.address();
console.log(`Server is listening on: http://${address}:${port}`);
})
The .createServer() method takes a single argument in the form of a callback function.
This callback function has two primary arguments; the request (commonly written as
req) and the response (commonly written as res).
The req object contains all of the information about an HTTP request ingested by the
server. It exposes information such as the HTTP method (GET,POST, etc.), the
pathname, headers, body, and so on. The res object contains methods and properties
pertaining to the generation of a response by the HTTP server. This object contains
methods such as .setHeader (sets HTTP headers on the response), .statusCode (set the
status code of the response), and .end() (dispatches the response to the client who
made the request). In the example above, we use the .end() method to send the string
‘Server is Running!’ to the client, which will display on the web page.
Once the .createServer() method has instantiated the server, it must begin listening
for connections. This final step is accomplished by the .listen() method on the server
instance. This method takes a port number as the first argument, which tells the server
to listen for connections at the given port number. In our example above, the server
has been set to listen on port 8080. Additionally, the .listen() method takes an optional
callback function as a second argument, allowing it to carry out a task after the server
has successfully started.
response.end([data], [encoding]); This method signals to the server that all of the
response headers and body have been sent; that
server should consider this message complete.
The method, response.end(), MUST be called on
each response.
The callback function that we saw above when we created the server has two
parameters namely, request and response.
The request object has url property and it holds the requested url. So, we will use it.
The response object has writeHead method which helps in setting the header. Then
we have the write method that helps to write the response body. And there is end
method which helps in sending the response.
Lets say, we want to print out the message Hello World! when we visit the home page
at http://localhost:9000. As, it is the home page so we have to check for /.
Now, stop the running server in the terminal and re-run it. Now, visit the home
page http://localhost:9000 url. This time we will see the message Hello World!
This happens because we are not handling the /some-unknown-page and hence the
else-block is executed which gives the Bad request! message as response.
http.request(Options_Object, Callback_Function)
The first argument is a string with the API endpoint. The second argument is a
JavaScript object containing all the options for the request. The last argument is a
callback function to handle the response.
path Request path. Defaults to '/'. Should include query string if any. E.G.
'/index.html?page=12'
res.on('data', d => {
process.stdout.write(d)
})
})
req.end()
MongoDB and Its Features
MongoDB is a document-oriented NoSQL database used for high volume data
storage. Instead of using tables and rows as in the traditional relational databases,
MongoDB makes use of collections and documents. Documents consist of key-value
pairs which are the basic unit of data in MongoDB. Collections contain sets of
documents and function which is the equivalent of relational database tables.
MongoDB is a database which came into light around the mid-2000s
You can perform operations using the `db` variable. Every collection has a property
on the `db` variable - e.g. the `apples` collection is `db.apples`.
MongoDB Connectivity: Create a Database
To create a database in MongoDB, start by creating a MongoClient object, then specify
a connection URL with the correct ip address and the name of the database you want
to create.
MongoDB will create the database if it does not exist, and make a connection to it.
The first parameter of the insertOne() method is an object containing the name(s) and
value(s) of each field in the document you want to insert.
It also takes a callback function where you can work with any errors, or the result of
the insertion:
No parameters in the find() method gives you the same result as SELECT * in MySQL.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
Web servers usually deliver html documents along with images, style sheets,
and scripts.
Most of the web servers support server-side scripts, using scripting languages
or redirecting the task to an application server which retrieves data from a
database and performs complex logic and then sends a result to the HTTP client
through the Web server.
Apache web server is one of the most commonly used web servers. It is an
open source project.
Server − This layer has the Web server which can intercept the requests made
by the clients and pass them the response.
Business − This layer contains the application server which is utilized by the
web server to do the required processing. This layer interacts with the data layer
via the database or some external programs.
Data − This layer contains the databases or any other source of data.
Node.js Web Server
➢ To access web pages of any web application, you need a web server.
➢ The web server will handle all the http requests for the web application
➢ e.g IIS is a web server for ASP.NET web applications and Apache is a
web server for PHP or Java web applications.
➢ Node.js provides capabilities to create your own web server which will
handle HTTP requests asynchronously.
➢ You can use IIS or Apache to run Node.js web application but it is
recommended to use Node.js web server.
Create server − A server which will listen to client's requests similar to Apache
HTTP Server. Node.js has a built-in module called HTTP, which allows Node.js
to transfer data over the Hyper Text Transfer Protocol (HTTP).
Read request and return response − The server created in an earlier step will
read the HTTP request made by the client which can be a browser or a console
and return the response.
Creating Node.js Application
We use the require directive to load the http module and store the returned
HTTP instance into an http variable as follows
$node app.js
});
The next step is to call createServer() method of http and specify callback
function with request and response parameter.
Finally, call listen() method of server object which was returned from
createServer() method with port number, to start listening to incoming requests
on port 5000.
The request object can be used to get information about the current HTTP
request e.g., url, request header, and data.
The response object can be used to send a response for a current HTTP
request.
Ex:
Properties
http.METHODS
> require('http').METHODS
http.STATUS_CODES
This property lists all the HTTP status codes and their description:
> require('http').STATUS_CODES
http.globalAgent
It is used to manage connections persistence and reuse for HTTP clients, and it's
a key component of Node.js HTTP networking.
Methods
http.createServer()
Usage:
http.request()
http.get()
Similar to http.request(), but automatically sets the HTTP method to GET, and
calls req.end() automatically.
Classes
• http.Agent
• http.ClientRequest
• http.Server
• http.ServerResponse
• http.IncomingMessage
http.Agent
This object makes sure that every request made to a server is queued and a
single socket is reused.
http.ClientRequest
When a response is received, the response event is called with the response,
with an http.IncomingMessage instance as argument.
http.Server
This class is commonly instantiated and returned when creating a new server
using http.createServer().
Once you have a server object, you have access to its methods:
The method you'll always call in the handler is end(), which closes the response,
the message is complete and the server can send it to the client. It must be called
on each response.
• getHeaderNames() get the list of the names of the HTTP headers already
set
• getHeaders() get a copy of the HTTP headers already set
• setHeader('headername', value) sets an HTTP header value
• getHeader('headername') gets an HTTP header already set
• removeHeader('headername') removes an HTTP header already set
• hasHeader('headername') return true if the response has that header set
• headersSent() return true if the headers have already been sent to the
client
After processing the headers you can send them to the client by
calling response.writeHead(), which accepts the statusCode as the first
parameter, the optional status message, and the headers object.
To send data to the client in the response body, you use write(). It will send
buffered data to the HTTP response stream.
http.IncomingMessage
Client.js
body+= data;
});
}
//make a request to the server
var req = http.request(options,callback);
req.end(); */
/*fetch('http://localhost:8081/sample.json', {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
})
.then(res => res.json())
.then(res => console.log(res));
*/
fetch('http://localhost:8081/sample.json', {
method: 'POST',
body: JSON.stringify({"name":"Aruna modified","col":"MIT"}),
headers: { 'Content-Type': 'application/json' },
})
.then(res => console.log(res));
Server.js
//create a server
http.createServer(function (request, response) {
if (request.method == "GET") {
//Read the requested file content from filesystem
// fs.readFile(pathname.substr(1), function (err, data) {
// if (err) {
// console.log(err);
// //HTTP Status 404 not found
// response.writeHead(404, { 'Content-Type': 'text/html' });
// }
// else {
// //page found and status of 200 has to be returned
// response.writeHead(200, { 'Content-Type': 'text/html' });
// });
//Read from the mongodb
console.log('executing mongo');
MongoClient.connect("mongodb://localhost:27017", {
useUnifiedTopology:
true
}, function (err, client) {
console.log("Connected successfully to server");
const db = client.db("pes");
db.collection("student").find({}).toArray(function (err, docs) {
response.writeHead(200, { 'Content-Type': 'application/json' });
//write the content of the file to response body
response.write(JSON.stringify(docs));
client.close();
response.end();
});
});
}
else {
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// at this point, `body` has the entire request body stored in it as a string
});
// write to file
// fs.writeFile(pathname.substr(1), body, (err, res) => {
// response.writeHead(200, { 'Content-Type': 'application/json' });
// response.end();
// });
//write to mongodb
console.log('executing mongo');
MongoClient.connect("mongodb://localhost:27017", {
useUnifiedTopology:
true
}, function (err, client) {
console.log("Connected successfully to server");
const db = client.db("pes");
db.collection("student").insertOne(JSON.parse(body)).then(r => {
response.writeHead(200, { 'Content-Type': 'application/json' });
//write the content of the file to response body
client.close();
response.end();
})
});
}
}).listen(8081);
console.log('server running at the link http://localhost/8081');
Parse an address with the url.parse() method, and it will return a URL object
with each part of the address as properties:
HTTP Module
Node.js has a built-in module called HTTP, which allows Node.js to transfer data over
the Hyper Text Transfer Protocol (HTTP).
To process HTTP requests in JavaScript and Node.js, we can use the built-in http
module. This core module is key in leveraging Node.js networking and is extremely
useful in creating HTTP servers and processing HTTP requests.
The http module comes with various methods that are useful when engaging with
HTTP network requests. One of the most commonly used methods within the http
module is the .createServer() method. This method is responsible for doing exactly
what its namesake implies; it creates an HTTP server. To implement this method to
create a server, the following code can be used:
server.listen(8080, () => {
const { address, port } = server.address();
console.log(`Server is listening on: http://${address}:${port}`);
})
The .createServer() method takes a single argument in the form of a callback function.
This callback function has two primary arguments; the request (commonly written as
req) and the response (commonly written as res).
The req object contains all of the information about an HTTP request ingested by the
server. It exposes information such as the HTTP method (GET,POST, etc.), the
pathname, headers, body, and so on. The res object contains methods and properties
pertaining to the generation of a response by the HTTP server. This object contains
methods such as .setHeader (sets HTTP headers on the response), .statusCode (set the
status code of the response), and .end() (dispatches the response to the client who
made the request). In the example above, we use the .end() method to send the string
‘Server is Running!’ to the client, which will display on the web page.
Once the .createServer() method has instantiated the server, it must begin listening
for connections. This final step is accomplished by the .listen() method on the server
instance. This method takes a port number as the first argument, which tells the server
to listen for connections at the given port number. In our example above, the server
has been set to listen on port 8080. Additionally, the .listen() method takes an optional
callback function as a second argument, allowing it to carry out a task after the server
has successfully started.
response.end([data], [encoding]); This method signals to the server that all of the
response headers and body have been sent; that
server should consider this message complete.
The method, response.end(), MUST be called on
each response.
The callback function that we saw above when we created the server has two
parameters namely, request and response.
The request object has url property and it holds the requested url. So, we will use it.
The response object has writeHead method which helps in setting the header. Then
we have the write method that helps to write the response body. And there is end
method which helps in sending the response.
Lets say, we want to print out the message Hello World! when we visit the home page
at http://localhost:9000. As, it is the home page so we have to check for /.
Now, stop the running server in the terminal and re-run it. Now, visit the home
page http://localhost:9000 url. This time we will see the message Hello World!
This happens because we are not handling the /some-unknown-page and hence the
else-block is executed which gives the Bad request! message as response.
http.request(Options_Object, Callback_Function)
The first argument is a string with the API endpoint. The second argument is a
JavaScript object containing all the options for the request. The last argument is a
callback function to handle the response.
path Request path. Defaults to '/'. Should include query string if any. E.G.
'/index.html?page=12'
res.on('data', d => {
process.stdout.write(d)
})
})
req.end()
MongoDB and Its Features
MongoDB is a document-oriented NoSQL database used for high volume data
storage. Instead of using tables and rows as in the traditional relational databases,
MongoDB makes use of collections and documents. Documents consist of key-value
pairs which are the basic unit of data in MongoDB. Collections contain sets of
documents and function which is the equivalent of relational database tables.
MongoDB is a database which came into light around the mid-2000s
You can perform operations using the `db` variable. Every collection has a property
on the `db` variable - e.g. the `apples` collection is `db.apples`.
MongoDB Connectivity: Create a Database
To create a database in MongoDB, start by creating a MongoClient object, then specify
a connection URL with the correct ip address and the name of the database you want
to create.
MongoDB will create the database if it does not exist, and make a connection to it.
The first parameter of the insertOne() method is an object containing the name(s) and
value(s) of each field in the document you want to insert.
It also takes a callback function where you can work with any errors, or the result of
the insertion:
No parameters in the find() method gives you the same result as SELECT * in MySQL.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
Introduction to mongodb.connect
This method is used to connect the Mongo DB server with our Node application. This is an
asynchronous method from MongoDB module.
Syntax
mongodb.connect(path[, callback])
Parameters
•path – The server path where the MongoDB server is actually running along with its port.
•callback – This function will give a callback if any error occurs.
MongoDB
To be able to experiment with the code examples, you will need access to a MongoDB
database.
Creating a Database
In the above example, we have imported mongodb module (native drivers) and got the
reference of MongoClient object. Then we used MongoClient.connect() method to get the
reference of specified MongoDB database. The specified URL
"mongodb://localhost:27017/pes" points to your local MongoDB database created in
MyMongoDB folder. The connect() method returns the database reference if the specified
database is already exists, otherwise it creates a new database.
In MongoDB, a database is not created until it gets content!
MongoDB waits until you have created a collection (table), with at least one document
(record) before it actually creates the database (and collection).
MongoDB waits until you have inserted a document before it actually creates the collection.
Insert a single document Into Collection
The first parameter of the insertOne() method is an object containing the name(s) and
value(s) of each field in the document you want to insert.
It also takes a callback function where you can work with any errors, or the result of the
insertion:
The first parameter of the insertMany() method is an array of objects, containing the data
you want to insert.
It also takes a callback function where you can work with any errors, or the result of the
insertion:
];
dbo.collection("students").insertMany(myobj, function(err, res) {
if (err) throw err;
console.log("Number of documents inserted: " + res.insertedCount);
db.close();
});
});
If you do not specify an _id field, then MongoDB will add one for you and assign a unique id
for each document.
MongoDB assigns a unique _id for each document. The value must be unique for each
document:
In MongoDB we use the find and findOne methods to find data in a collection.
Just like the SELECT statement is used to find data in a table in a MySQL database.
Find:
To select data from a table in MongoDB, we can also use the find() method.
Examples:
node-js-mongodb-create-collection.js
node-js-mongodb-delete-collection.js
// example : delete 'users' collection in newdb database
var url = "mongodb://localhost:27017/newdb";
node-js-mongodb-insert-document.js
// document to be inserted
var doc = { name: "Roshan", age: "22" };
node-js-mongodb-insert-many-documents.js
// documents to be inserted
var docs = [{ name: "Udat", age: "21" },
{ name: "Karthik", age: "24" },
{ name: "Anil", age: "23" }];
// insert multiple documents to 'users' collection using insertOne
db.collection("users").insertMany(docs, function(err, res) {
if (err) throw err;
console.log(res.insertedCount+" documents inserted");
// close the connection to db when you are done with it
db.close();
});
});
Output
$ node node-js-mongodb-insert-many-documents.js
Switched to newdb database
3 documents inserted
References:
1. https://www.tutorialkart.com/nodejs/node-js-mongodb/
2. https://www.tutorialsteacher.com/nodejs
Event Emitter Module
Event Loop
Node.js is a single-threaded application, but it can support concurrency via the concept
of event and callbacks. Every API of Node.js is asynchronous and being single-threaded,
they use async function calls to maintain concurrency. Node uses observer pattern. Node
thread keeps an event loop and whenever a task gets completed, it fires the corresponding
event which signals the event-listener function to execute.
Event-Driven Programming
Node.js uses events heavily and it is also one of the reasons why Node.js is pretty fast
compared to other similar technologies. As soon as Node starts its server, it simply initiates
its variables, declares functions and then simply waits for the event to occur.
In an event-driven application, there is generally a main loop that listens for events, and
then triggers a callback function when one of those events is detected.
Although events look quite similar to callbacks, the difference lies in the fact that callback
functions are called when an asynchronous function returns its result, whereas event
handling works on the observer pattern. The functions that listen to events act
as Observers. Whenever an event gets fired, its listener function starts executing. Node.js
has multiple in-built events available through events module and EventEmitter class which
are used to bind events and event-listeners as follows −
// Import events module
var events = require('events');
Node.js allows us to create and handle custom events easily by using events module. Event
module includes EventEmitter class which can be used to raise and handle custom events.
Many objects in a Node emit events, for example, a net.Server emits an event each time a
peer connects to it, an fs.readStream emits an event when the file is opened. All objects
which emit events are the instances of events.EventEmitter.
EventEmitter class lies in the events module. It is accessible via the following code −
// Import events module
var events = require('events');
When an EventEmitter instance faces any error, it emits an 'error' event. When a new
listener is added, 'newListener' event is fired and when a listener is removed,
'removeListener' event is fired.
EventEmitter provides multiple properties like on and emit. on property is used to bind a
function with the event and emit is used to fire an event.
Example: Raise and Handle Node.js events
// get the reference of EventEmitter class of events module
var events = require('events');
The emit() function raises the specified event. First parameter is name of the event as a
string and then arguments. An event can be emitted with zero or more arguments. You can
specify any name for a custom event in the emit() function.
Methods
1 addListener(event, listener)
Adds a listener at the end of the listeners array for the specified event. No checks
are made to see if the listener has already been added. Multiple calls passing the
same combination of event and listener will result in the listener being added
multiple times. Returns emitter, so calls can be chained.
2 on(event, listener)
Adds a listener at the end of the listeners array for the specified event. No checks
are made to see if the listener has already been added. Multiple calls passing the
same combination of event and listener will result in the listener being added
multiple times. Returns emitter, so calls can be chained.
3 once(event, listener)
Adds a one time listener to the event. This listener is invoked only the next time the
event is fired, after which it is removed. Returns emitter, so calls can be chained.
4 removeListener(event, listener)
Removes a listener from the listener array for the specified event. Caution − It
changes the array indices in the listener array behind the listener. removeListener
will remove, at most, one instance of a listener from the listener array. If any single
listener has been added multiple times to the listener array for the specified event,
then removeListener must be called multiple times to remove each instance.
Returns emitter, so calls can be chained.
5 removeAllListeners([event])
Removes all listeners, or those of the specified event. It's not a good idea to remove
listeners that were added elsewhere in the code, especially when it's on an emitter
that you didn't create (e.g. sockets or file streams). Returns emitter, so calls can be
chained.
6 setMaxListeners(n)
By default, EventEmitters will print a warning if more than 10 listeners are added
for a particular event. This is a useful default which helps finding memory leaks.
Obviously not all Emitters should be limited to 10. This function allows that to be
increased. Set to zero for unlimited.
7 listeners(event)
Returns an array of listeners for the specified event.
Class Methods
1 listenerCount(emitter, event)
Returns the number of listeners for a given event.
Events
1 newListener
• event − String: the event name
• listener − Function: the event handler function
This event is emitted any time a listener is added. When this event is triggered, the
listener may not yet have been added to the array of listeners for the event.
2 removeListener
• event − String The event name
• listener − Function The event handler function
This event is emitted any time someone removes a listener. When this event is
triggered, the listener may not yet have been removed from the array of listeners for
the event.
There are two common patterns that can be used to raise and bind an event using
EventEmitter class in Node.js.
In this pattern, a constructor function returns an EventEmitter object, which was used to
emit events inside a function. This EventEmitter object can be used to subscribe for the
events.
In this pattern, we can extend the constructor function from EventEmitter class to emi t
the events so that you can use EventEmitter class to raise and handle custom events in
Node.js.
Example:
// Import events module
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();
React Router is a standard library system built on top of the React and used to create
routing in the React application using React Router Package. It provides the synchronous
URL on the browser with data that will be displayed on the web page. It maintains the
standard structure and behavior of the application and mainly used for developing single
page web applications.
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
, document.getElementById('app))
Route
Route allows you to map your app’s location to different React components. For example,
say we wanted to render a Dashboard component whenever a user navigated to the
/dashboard path. To do so, we’d render a Route that looked like this.
With our Route elements in this configuration, it’s possible for multiple routes to match on a
single URL. You might want to do that sometimes, but most often you want React Router to
only render the route that matches best. Fortunately, we can easily do that with Routes.
Routes
Whenever you have one or more Routes, you’ll most likely want to wrap them in a Routes.
import {
Routes,
Route
} from 'react-router-dom'
function App () {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/settings" element={<Settings />} />
<Route path="*" element={<NotFound />} />
</Routes>
)
}
The reason for this is because it’s Routes job is to understand all of its children Route
elements, and intelligently choose which ones are the best to render. Once we start adding
more complex Routes to our application, Routes will start to do more work like enabling
intelligent rendering and relative paths.
Link
The next step is being able to navigate between them. This is the purpose of the Link
component.
To tell Link what path to take the user to when clicked, you pass it a to prop.
<nav>
<Link to="/">Home</Link>
<Link to='/about'>About</Link>
<Link to="/settings">Settings</Link>
</nav>
If you need more control over Link, you can also pass to as an object. Doing so allows you to
add a query string via the search property or pass along any data to the new route via state.
<nav>
<Link to='/'>Home</Link>
<Link to='/about'>About</Link>
<Link to={{
pathname: '/settings',
search: '?sort=date',
state: { fromHome: true },
}}>Settings</Link>
</nav>
We’ll cover state, Query Strings, and how React Router supports relative paths in more
depth later on in this post.
At this point we’ve covered both the history and the absolute fundamentals of React
Router, but one thing should already be clear - by embracing composition, React Router is
truly a router for React. I believe React will make you a better JavaScript developer and
React Router will make you a better React developer.
Now, instead of just walking you through the rest of the API, we’ll take a more practical
approach by breaking down all of the common use cases you’ll need when using React
Router.
URL Parameters
Like function parameters allow you to declare placeholders when you define a function, URL
Parameters allow you to declare placeholders for portions of a URL. For example, When you
visit a topic on Wikipedia, you’ll notice that the URL pattern is always the same,
wikipedia.com/wiki/{topicId}.
Instead of defining a route for every topic on the site, they can declare one route with a
placeholder for the topic’s id. The way you tell React Router that a certain portion of the
URL is a placeholder (or URL Parameter), is by using a : in the Route’s path prop.
Example
Step-1: In our project, we will create two more components along with App.js, which is
already present.
About.js
Contact.js
App.js
Index.js
References:
1. https://ui.dev/react-router-tutorial/#routes
2. https://www.javatpoint.com/react-router
React Router
Routing is a process in which a user is directed to different pages based on their action or
request. ReactJS Router is mainly used for developing Single Page Web Applications. React
Router is used to define multiple routes in the application. When a user types a specific URL
into the browser, and if this URL path matches any 'route' inside the router file, the user will
be redirected to that particular route.
React Router is a standard library system built on top of the React and used to create
routing in the React application using React Router Package. It provides the synchronous
URL on the browser with data that will be displayed on the web page. It maintains the
standard structure and behavior of the application and mainly used for developing single
page web applications.
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
, document.getElementById('app))
Route
Route allows you to map your app’s location to different React components. For example,
say we wanted to render a Dashboard component whenever a user navigated to the
/dashboard path. To do so, we’d render a Route that looked like this.
With our Route elements in this configuration, it’s possible for multiple routes to match on a
single URL. You might want to do that sometimes, but most often you want React Router to
only render the route that matches best. Fortunately, we can easily do that with Routes.
Routes
Whenever you have one or more Routes, you’ll most likely want to wrap them in a Routes.
import {
Routes,
Route
} from 'react-router-dom'
function App () {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/settings" element={<Settings />} />
<Route path="*" element={<NotFound />} />
</Routes>
)
}
The reason for this is because it’s Routes job is to understand all of its children Route
elements, and intelligently choose which ones are the best to render. Once we start adding
more complex Routes to our application, Routes will start to do more work like enabling
intelligent rendering and relative paths.
Link
The next step is being able to navigate between them. This is the purpose of the Link
component.
To tell Link what path to take the user to when clicked, you pass it a to prop.
<nav>
<Link to="/">Home</Link>
<Link to='/about'>About</Link>
<Link to="/settings">Settings</Link>
</nav>
If you need more control over Link, you can also pass to as an object. Doing so allows you to
add a query string via the search property or pass along any data to the new route via state.
<nav>
<Link to='/'>Home</Link>
<Link to='/about'>About</Link>
<Link to={{
pathname: '/settings',
search: '?sort=date',
state: { fromHome: true },
}}>Settings</Link>
</nav>
We’ll cover state, Query Strings, and how React Router supports relative paths in more
depth later on in this post.
At this point we’ve covered both the history and the absolute fundamentals of React
Router, but one thing should already be clear - by embracing composition, React Router is
truly a router for React. I believe React will make you a better JavaScript developer and
React Router will make you a better React developer.
Now, instead of just walking you through the rest of the API, we’ll take a more practical
approach by breaking down all of the common use cases you’ll need when using React
Router.
URL Parameters
Like function parameters allow you to declare placeholders when you define a function, URL
Parameters allow you to declare placeholders for portions of a URL. For example, When you
visit a topic on Wikipedia, you’ll notice that the URL pattern is always the same,
wikipedia.com/wiki/{topicId}.
Instead of defining a route for every topic on the site, they can declare one route with a
placeholder for the topic’s id. The way you tell React Router that a certain portion of the
URL is a placeholder (or URL Parameter), is by using a : in the Route’s path prop.
Example
Step-1: In our project, we will create two more components along with App.js, which is
already present.
About.js
Contact.js
App.js
Index.js
References:
1. https://ui.dev/react-router-tutorial/#routes
2. https://www.javatpoint.com/react-router