# IUG NODE JS
## CORE MODULES
### GLOBALS
1. global classes example (Math class)
```jsx=
cont val = Math.abs(-5);
```
2. global functions example (fetch)
```jsx=
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
```
3. global variables
* process
* info about environment
```jsx=
console.log(process.env)
```
* info about current process running files
```jsx=
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
```jsx=
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**
```jsx=
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**
```jsx=
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
```jsx=
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
}
})
```
2. Read (readFile , readFileSync)
**NOTE:** readFile run in async thread (libuv) but readFileSync run in sync thread (call stack).
```jsx=
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)
```
3. write (writeFile , writeFileSync)
**NOTE:** writeFile run in async thread (libuv) but writeFileSync run in sync thread (call stack).
```jsx=
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.**
```jsx=
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:
```jsx=
// 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
```jsx=
// > 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.
```javascript=
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'));
```
```xml=
> 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
```jsx=
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**
```jsx=
> 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
```
8. **`npm view <package-name>`:** this command displays information about the specified <package-name>, including its name, version, description, keywords, and maintainers.
9. **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**
```json=
{
"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:**
```javascript=
const http = require('http');
cont server = http.createServer();
server.listen(8888 , () => {
console.log('the server now listening on port 8888')
})
```
### **2. Application:**
```javascript=
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:**
```javascript=
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:
```javascript=
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
```javascript=
// 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.
```javascript=
// 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:**
```javascript=
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.
```javascript=
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
```javascript=
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