# 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