IUG NODE JS

CORE MODULES

GLOBALS

  1. global classes example (Math class)
cont val = Math.abs(-5);
  1. global functions example (fetch)
fetch('https://jsonplaceholder.typicode.com/todos/1') .then(response => response.json()) .then(json => console.log(json))
  1. global variables
  • process
    • info about environment
    ​​​​console.log(process.env)
    • info about current process running files
    ​​​​console.log(process.argv) ​​​​//! info about current process running files ​​​​/*[ ​​​​'C:\Program Files\nodejs\node.exe', ​​​​'D:\Node js\modules\core_modules\globals' ​​​​]*/
    • info about current memory (RAM) status
    ​​​​console.log(process.memoryUsage()) ​​​​/*{ ​​​​ rss: 27533312, ​​​​ heapTotal: 6369280, ​​​​ heapUsed: 5712920, ​​​​ external: 429451, ​​​​ arrayBuffers: 17378 ​​​​}*/
  • global: contain info about the app.
  • __dirname: the path of the current file without the file name.
  • __filename: the path of the current file including the file name.

EVENTES

Event: is an signal that broadcast over the app when specific event occur.

Event listener: is a function in a computer program that waits for an event to occur.
Example of event listener

const http = require('http'); const server = http.createServer(); // "listening" is the event name // the callback function will be executed automatically when the event occurs server.on("listening", () => { console.log("server is listening now") }) server.listen(3000)

Event emitter: Js class that enables you to create custom events that can be emitted later
Example of event emitter

const { EventEmitter } = require('events'); const MyEvent = new EventEmitter(); // event names const MY_EVENTS = { EVENT1: "EVENT1", EVENT2: "EVENT2", } // define event listeners MyEvent.on(MY_EVENTS.EVENT1, () => { console.log("EVENT 1 FIRED") }) MyEvent.on(MY_EVENTS.EVENT2, () => { console.log("EVENT 2 FIRED") }) // fire events MyEvent.emit(MY_EVENTS.EVENT1); MyEvent.emit(MY_EVENTS.EVENT2);

FILE SYSTEM (fs)

  1. info about files
const { open, stat } = require('fs'); // 1. stat: get info about the file stat('./data.txt', (err, info) => { if (err) { console.log(err); return } console.log(info) }) //2. open: check if the file exists or not open('./data.txt', (err, path) => { if (err) { // if error the file not exists console.log(err) return; } else { // the file exists you can do whatever you want } })
  1. Read (readFile , readFileSync)
    NOTE: readFile run in async thread (libuv) but readFileSync run in sync thread (call stack).
const { readFile, readFileSync } = require('fs'); // async readFile('./data.txt', 'utf-8', (error, data) => { if (error) { console.log(error) return } console.log("*".repeat(10) + " async " + "*".repeat(10)) console.log(data) }) // sync const data = readFileSync('./data.txt', 'utf-8'); console.log("*".repeat(10) + " sync " + "*".repeat(10)) console.log(data)
  1. write (writeFile , writeFileSync)
    NOTE: writeFile run in async thread (libuv) but writeFileSync run in sync thread (call stack).
const { open, writeFile } = require("fs"); // the second parameter is the open mode and 'a+' mean append open('./data.txt', 'a+', (error, fileDescriptor) => { if (error) { console.log(error) return } writeFile(fileDescriptor, "lorem lorem lorem lorem\n", (error) => { if (error) { console.log(error) } }) }) // OR YOU CAN APPEND ON FILE LIKE THIS writeFile('./data.txt', "\nlorem lorem lorem lorem", { flag: 'a', encoding: "utf-8" }, (error) => { if (error) { console.log(error) } })

Streams

Stream: objects that let you read data from a source and write data to a destination at the same time.

how stream work?
Stream split the data into small chunks and when the chunk is ready the stream pipe can handle it.

Example of stream: suppose that we have a very large file named input.txt and we want to copy its content to another file output.txt if we use the normal way read all the file and store it in the memory, then write it to the output.txt this may take a long time and the memory resource will be allocated for only this process,
but if we use streams the input file will be split into chunks and when a chunk is ready it will be delivered to the write stream to write it to the output file this will reduce the time and memory usage.

const { createReadStream, createWriteStream } = require("fs"); const readStream = createReadStream('./input.txt'); const writeStream = createWriteStream('./output.txt'); readStream.pipe(writeStream);

Stream types:

  1. Read stream: stream which is used for read operation.
  2. Write stream: stream which is used for read operation.
  3. Duplex: stream which is used for read and write operations. (example socket)
  4. Transform: type of duplex stream where the output is computed based on input.

PATH

  1. __filename: returns the absolute path of the current file.
  2. __dirname: returns the absolute path of the directory containing the current file.
  3. process.cwd(): returns the current working directory of the Node.js process ,from where i started this process ?

Example:

// home/user/index.js console.log("__filename: " + __filename); console.log("__dirname: " + __dirname); console.log("process.cwd(): " + process.cwd()); // home/test/index.js require("../user")

Output

// > node /home/test __filename: /home/user/index.js __dirname: /home/user process.cwd(): /home/test

As you can see process.cwd() returns the current working directory of the Node.js process, which is the directory from which the process was started.

PATH MODULE

  1. path.dirname("/the-path"): Returns the directory path from a file path same as __dirname global.
  2. path.basename("/the-path"): Returns the base filename from a file path.
  3. path.extname("/the-path"): Returns the file extension from a file path.
  4. path.parse("/the-path"): Parses a file path into an object with root, dir, base, name, and ext properties.
  5. path.join("/the-path"): Joins one or more path segments together into a single path, its recomeended to use path.join() because different operating systems use different path separators to represent file paths.
const path = require("path"); console.log(`DIR NAME: ${path.dirname(__filename)}`) console.log(`BASE (FILE) NAME: ${path.basename(__filename)}`) console.log(`EXTENSION NAME: ${path.extname(__filename)}`) console.log(`PARSE PATH :`, path.parse(__filename)); console.log(`JOIN ('home' , 'data' , 'text.txt') :`, path.join('home' , 'data' , 'text.txt'));
> node .\path\index.js DIR NAME: D:\university\semester 2\Node js\Code\IUG_NODE_JS\modules\core_modules\path BASE (FILE) NAME: index.js EXTENSION NAME: .js PARSE PATH : { root: 'D:\\', dir: 'D:\\university\\semester 2\\Node js\\Code\\IUG_NODE_JS\\modules\\core_modules\\path', base: 'index.js', ext: '.js', name: 'index' } JOIN ('home' , 'data' , 'text.txt') : home\data\text.txt

NPM MODULES

what is npm ?

npm stands for Node Package Manager. It is a command-line tool used to install, manage, and publish packages (libraries and tools) for Node.js.

  1. npm init, a command-line tool that is used to create a new package.json file for a Node.js project.

  2. package.json: is a configuration file that is used to define metadata about a Node.js project, including its dependencies, scripts, and other settings.

  3. package-lock.json: is a lock file that is created by NPM to lock down the specific version of each package that is installed in a project. It is used to ensure that all installations of a project use the same version of each package.

  4. node_modules: is a directory that is created by NPM to store all of the packages that a project depends on. When you install a package using NPM, it will be downloaded and stored in the node_modules directory.

how to require npm module ?

to require npm modules you can use the same syntax as requiring any core module

const _ = require('lodash');

npm commands

  1. npm (install || i) <package-name>: this command installs the specified <package-name> as a dependency for your node.js project. "I" stands for "install" and is shorthand for npm install.

  2. npm (install || i): used in to install the necessary dependencies listed in the project's package.json file.

  3. npm (install || i) -g <package-name>: this command is used to install a Node.js package globally on your system.

  4. npm (install || i) --save-dev <package-name>: this command installs the specified <package-name> as a development dependency for your node.js project, save-dev flag tells NPM to add the package to the devDependencies section of your package.json file.

  5. npm (uninstall || un) <package-name>: this command is used to uninstall a package that was previously installed with npm.

  6. npm list: this command lists all the packages installed in your project.

  7. npm list --depth=1: this command lists all the packages installed in your project and their level-one dependencies

Example

> npm list // default depth is equal to 0 └── cors@2.8.5 > npm list --depth=1 └─┬ cors@2.8.5 ├── object-assign@4.1.1 └── vary@1.1.2
  1. npm view <package-name>: this command displays information about the specified <package-name>, including its name, version, description, keywords, and maintainers.

  2. update existing packages:

    • npm i -g npm-check-updates: This command installs npm-check-updates globally, this package is a utility tool that helps you keep your Node.js project dependencies up to date
    • ncu: used to check for available updates to your Node.js project dependencies listed in the package.json file.
    • ncu -u: this command is used to check for available updates to your Node.js project dependencies and replace all available versions, including those that may have breaking changes.
      note: this only change the version number but does not install the new package so you need to run npm i command to install the new version.

10.npm search _____: to search for a specific package or a keyword on the npm registry

version number format (major.minor.batch)

  1. Major: This indicates significant changes to the software that may affect its compatibility with other software or systems.

  2. Minor: This indicates smaller updates or improvements to the software that may not affect compatibility.

  3. Batch (or Patch): This indicates a small update or fix to the software, often to address a specific issue or bug that has been discovered since the last release. It usually does not include any new features or major changes.

So, for example, a version number of "3.1.2" would indicate a major version of 3, a minor version of 1, and a batch (or patch) version of 2.

package.json

is a metadata file in JSON format, which is used to manage and describe a Node.js project's dependencies, scripts, and other project-specific details.

  1. name: A string that specifies the name of the package.

  2. version: A string that specifies the version of the package.

  3. description: A brief description of the package.

  4. keywords: An array of strings that describes the package in more detail, used for search optimization and categorization.

  5. license: A string that specifies the license under which the package is released.

  6. author: A string or an object that describes the author(s) of the package.

  7. repository: An object that describes the location of the package's source code repository.

  8. dependencies: An object that lists the package's dependencies and their respective versions.

  9. devDependencies: An object that lists the package's development dependencies and their respective versions.

  10. scripts: An object that lists custom scripts that can be executed with npm run.

Example

{ "name": "my-app", "version": "1.0.0", "description": "A simple web application built with Node.js and Express", "keywords": [ "node", "express", "web", "application" ], "license": "MIT", "author": { "name": "John Doe", "email": "john.doe@example.com", "url": "https://johndoe.com" }, "repository": { "type": "git", "url": "https://github.com/johndoe/my-app.git" }, "dependencies": { "express": "^4.17.1", "body-parser": "^1.19.0" }, "devDependencies": { "nodemon": "^2.0.12", "eslint": "^7.30.0" }, "scripts": { "start": "node index.js", "dev": "nodemon index.js", "lint": "eslint ." } }

Application vs Project

Application is a software program that is designed to perform a specific task or set of tasks,a project, on the other hand, is a set of related tasks that are undertaken to achieve a specific goal.

Feature Application Project
Purpose Designed to perform a specific task or set of tasks to achieve a specific goal
Scope Typically focused on a single task or set of tasks May involve multiple tasks that are interrelated

Example: application .jar file project java code

API

to build a backend application you need 3 important things.

1. Server:

const http = require('http'); cont server = http.createServer(); server.listen(8888 , () => { console.log('the server now listening on port 8888') })

2. Application:

const express = require('express'); cont app = express(); // link the application with the server cont server = http.createServer(app); server.listen(8888 , () => { console.log('the server now listening on port 8888') })

3. Routing:

Is the process of associating HTTP requests with specific functions(endpoints). This allows you to control how your application responds to different types of requests.

To define a route in express, you use the app.METHOD() method, where METHOD is the HTTP method, such as GET or POST

Example:

app.get('/', function(req, res, next) { res.send('<h1>Hello World from index</h1>'); }); app.get('/home', function(req, res, next) { res.send('<h1>Hello World from home</h1>'); });

In the Express.js framework, req, res, and next are three parameters that are passed to every route handler function.

req: is an object that contains information about the request, such as the URL, the HTTP method, and the headers.
res: is an object that can be used to send a response back to the client.
next: is a function that can be used to call the next middleware function in the stack.

(Res) most commonly used res methods:

res.send() // Sends a string back to the client. res.json() // Sends JSON data back to the client. res.html() // Sends HTML data back to the client. res.status() // Sets the HTTP status code of the response. res.redirect() // Redirects the client to a new URL. res.header() // Sets a response header. res.cookie() // Sets a cookie. res.end() // Ends the response.

(Req) how to receive data from client:

1. Query string: is a part of the URL that is used to pass data to the server, the query string is separated from the URL by a question mark ? and is made up of key-value pairs.
you can use the req.query object to access the query string

// Example url === /users?id=1 app.get("/users" , (req, res, next) => { const id = req.query.id; // id = 1 // ...etc })

2. Path parameters: part of the URL that are used to identify a specific resource on the server.
Example: /users/:id => /users/1 | /users/2 | /users/3 etc.
you can use the req.params object to access path parameters.

// Example url === /users/55 app.get("/users/:id" , (req, res, next) => { const id = req.params.id; // id = 55 // ...etc })

NOTES:

  • you can use more than one path pramaeter
  • ordere is very important
  • path parameters can be in any part of the URL
  • when there is more than one route match the requested url the express response using first match
    Example:
app.get("/users/all" , () => { console.log("all"); }) app.get("/users/:id" , () => { console.log("by id"); })

in the previous example if we request /user/all the output is “all” because it appeared first but if we flip the order the result well be “by id”.

3. Headers: a way to pass additional information with an HTTP request. Headers are key-value pairs, where the key is the name of the header and the value is the value of the header.
you can use the req.headers object or req.get("HEADER_NAME") function to access headers
NOTE: if you want to use .get function to access headers, header name must start with a capital letter.

app.get("/" , (req, res,next) => { const authToken = req.headers.authorization; // const authToken = req.get("Authorization"); })

4. body: COMING SOON

Middlewares

is a function that is used to process an HTTP request and response before the end point,used to perform tasks such as:

  • Logging requests and responses
  • Validating request data
  • Transforming request data
  • Generating responses
  • Caching responses
  • Routing requests to different handlers
    usually, it's used to add pre-conditions on requests.

To use middleware in Express, you can use the app.use() method

app.use((req, res, next) => { console.log('Request received:', req.method, req.url); next(); }); app.use((req, res) => { console.log('Response sent:', res.status, res.headers); });

NOTE: middleware next function let you go to the next middleware and if this is the last one in the chain next function move you to the target endpoint.
NOTE: middlewares ordder is important.
NOTE: middlewares layer is shared between all endpoints