└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # My Express.js Documentation 2 | 3 | ## Total Chapters are following 4 | 5 | 2. Express.js 6 | 1. introduction to express.js 7 | 2. express server 8 | 3. http methods and postman 9 | 4. Express Router 10 | 5. HTTP Response 11 | 6. HTTP Request part-1 12 | 7. HTTP Request part-2 13 | 8. HTTP Request part-3 14 | 9. send and receive from data 15 | 10. Area Calculator 16 | 11. How to set .env variables 17 | 12. Middlewares 18 | 13. express static Middlewares 19 | 14. MVC pattern 20 | 21 | 22 | ## Chapter 2: Express.js 23 | 24 | ### [2.1 Introduction to express.js](https://youtu.be/1Max9huISzA) 25 | 26 | - always check the documentation of [express.js](https://www.npmjs.com/package/express) 27 | - Express.js is a node.js framework which makes life easier 28 | - no more hassle of setting Content-Type 29 | - easy to learn and time saving facilitites available because we have ready made stuff in express.js 30 | - MERN Stack, NERD stack, PERN stack 31 | 32 | ### [2.2 creating express server](https://youtu.be/t9GVn5j1Hsw) 33 | 34 | - first initialize npm : `npm init -y` 35 | - install express: `npm install express` 36 | - example 37 | 38 | ```js 39 | const express = require("express"); 40 | 41 | const PORT = 3000; 42 | 43 | const app = express(); 44 | 45 | app.get("/", (req, res) => { 46 | res.send("

Welcome to express server

"); 47 | }); 48 | 49 | app.listen(PORT, () => { 50 | console.log(`server is running at http://localhost:${PORT}`); 51 | }); 52 | ``` 53 | 54 | ### [2.3 http methods and postman](https://youtu.be/AnCkn--EAas) 55 | 56 | - HTTP methods - get, post, put, patch, delete ... 57 | - get methods helps to get a resource or data 58 | - post method helps to create new resource 59 | - put method helps to update a resource 60 | - patch method helps to update single item of a resource 61 | - delete method helps to delete a resource 62 | - example 63 | 64 | ```js 65 | // index.js 66 | 67 | const express = require("express"); 68 | 69 | const PORT = 3000; 70 | 71 | const app = express(); 72 | 73 | // http://localhost:3000/user 74 | 75 | // this will work for all http methods: get, post so use app.get() or anything specific 76 | app.use("/user", (req, res) => { 77 | res.send("

Welcome to get request of express server

"); 78 | }); 79 | 80 | app.get("/user", (req, res) => { 81 | res.send("

Welcome to get request of express server

"); 82 | }); 83 | 84 | app.post("/user", (req, res) => { 85 | res.send("

Welcome to post request of express server

"); 86 | }); 87 | 88 | // put is for updating multiple property 89 | // patch is for updating one property 90 | 91 | app.put("/user", (req, res) => { 92 | res.send("

Welcome to put request of express server

"); 93 | }); 94 | 95 | app.patch("/user", (req, res) => { 96 | res.send("

Welcome to patch request of express server

"); 97 | }); 98 | 99 | app.delete("/user", (req, res) => { 100 | res.send("

Welcome to delete request of express server

"); 101 | }); 102 | 103 | app.listen(PORT, () => { 104 | console.log(`server is running at http://localhost:${PORT}`); 105 | }); 106 | 107 | // error handling 108 | app.use((req, res) => { 109 | res.send("

Page not found 404

"); 110 | }); 111 | 112 | app.use((err, req, res, next) => { 113 | console.error(err.stack); 114 | res.status(500).send("Something broke!"); 115 | }); 116 | ``` 117 | 118 | ### [2.4 Express Router](https://youtu.be/S7oFcdUiF1k) 119 | 120 | - use morgan package for getting more info about routing on console 121 | 122 | ```js 123 | step1 : npm install morgan 124 | step2 : const morgan = require("morgan"); 125 | step3 : app.use(morgan("dev")); 126 | ``` 127 | 128 | - example 129 | 130 | ```js 131 | // step1: creates a routes folder 132 | // setp2: create a file name as user.routes.js 133 | // step3: write the following code inside user.routes.js 134 | const express = require("express"); 135 | 136 | const router = express.Router(); 137 | 138 | // /users 139 | router.get("/", (req, res) => { 140 | res.send("I am get method of user route"); 141 | }); 142 | 143 | router.post("/", (req, res) => { 144 | res.send("I am post method of user route"); 145 | }); 146 | 147 | router.put("/", (req, res) => { 148 | res.send("I am put method of user route"); 149 | }); 150 | 151 | router.patch("/", (req, res) => { 152 | res.send("I am patch method of user route"); 153 | }); 154 | 155 | router.delete("/", (req, res) => { 156 | res.send("I am delete method of user route"); 157 | }); 158 | 159 | module.exports = router; 160 | 161 | //step4: write following code inside index.js 162 | const express = require("express"); 163 | 164 | const userRoutes = require("./routes/user.routes"); 165 | 166 | const PORT = 3000; 167 | 168 | const app = express(); 169 | 170 | app.use("/users", userRoutes); 171 | 172 | app.listen(PORT, () => { 173 | console.log(`server is running at http://localhost:${PORT}`); 174 | }); 175 | ``` 176 | 177 | - example 2 178 | 179 | ```js 180 | const express = require("express"); 181 | const router = express.Router(); 182 | 183 | // how to get the path 184 | const path = require("path"); 185 | 186 | const getFileLocation = (fileName) => { 187 | return path.join(__dirname, `../views/${fileName}`); 188 | }; 189 | 190 | router.get("/", (req, res) => { 191 | res.sendFile(getFileLocation("index.html")); 192 | }); 193 | router.get("/register", (req, res) => { 194 | res.sendFile(getFileLocation("register.html")); 195 | }); 196 | router.get("/login", (req, res) => { 197 | res.sendFile(getFileLocation("login.html")); 198 | }); 199 | module.exports = router; 200 | ``` 201 | 202 | ### [2.5 regular expression & wild card Router]() 203 | 204 | ```js 205 | //regular expression 206 | // we can use 0-9 but maximum 4 digits combination 207 | router.get("/search/:id([0-9]{4})", (req, res) => { 208 | res.status(200).send("serach user by id" + req.params.id); 209 | }); 210 | 211 | // only letters allowed with maximum 5 characters 212 | router.get("/search-username/:name([a-zA-Z]{5})", (req, res) => { 213 | res.status(200).send("serach user by name" + req.params.name); 214 | }); 215 | 216 | // wild cart 217 | router.get("*", (req, res) => { 218 | res.status(404).send({ 219 | message: "url not found", 220 | }); 221 | }); 222 | ``` 223 | 224 | ### [2.6 Express generator]() 225 | 226 | - package `npx espress-generator` 227 | - create a basic standard scalable folder structure with necessary codes 228 | 229 | ### [2.7 HTTP Response](https://youtu.be/S7oFcdUiF1k) 230 | 231 | - response can be text, html, json 232 | - res.send("some text here"); 233 | - res.status(statuscode).json({...}); 234 | - res.sendFile(fileName); 235 | - res.cookie(key, value); 236 | - res.clrarCookie(key); 237 | - res.writeHead() 238 | - res.write() 239 | - res.end() 240 | - res.append(key, value); this will set as response header 241 | 242 | ### [2.8 HTTP Request part-1](https://youtu.be/141Q7XhGGS8) 243 | 244 | - request with query parameter - req.query.parameterName 245 | - request with route parameters - req.params.parameterName 246 | - request with headers - req.header(key) 247 | - request with json data / form data inside body - req.body.parameterName 248 | - query parameter has question mark; search something on google. 249 | 250 | - example of query parameter - http://localhost:3000?id=101&name=anisul islam 251 | 252 | - we can get the value using req.query.id and req.query.name 253 | 254 | ```js 255 | router.post("/", (req, res) => { 256 | console.log(req.query); 257 | console.log(req.query.id); 258 | console.log(req.query.name); 259 | res.send("I am get method of user route"); 260 | }); 261 | ``` 262 | 263 | ### [2.9 HTTP Request part-2](https://youtu.be/141Q7XhGGS8) 264 | 265 | - example of routes parameter 266 | 267 | - http://localhost:3000/101 268 | - we can get the value using req.params.id 269 | 270 | ```js 271 | router.post("/:id", (req, res) => { 272 | console.log(req.params.id); 273 | res.send("I am get method of user route"); 274 | }); 275 | ``` 276 | 277 | - example of how to get data header requests 278 | 279 | ```js 280 | router.post("/", (req, res) => { 281 | console.log(req.header("id")); 282 | res.send("I am get method of user route"); 283 | }); 284 | ``` 285 | 286 | ### [2.10 HTTP Request part-3](https://youtu.be/141Q7XhGGS8) 287 | 288 | - example of request with json data 289 | 290 | - first add `app.use(express.json())`; for form data use `app.use(express.urlencoded({extended: true}))` 291 | - then access the data using `req.body.parameterName` 292 | 293 | ```js 294 | // sending json or from data when making request 295 | { 296 | "name" : "anisul" 297 | } 298 | 299 | router.post("/", (req, res) => { 300 | res.status(201).json({ 301 | message: "user is created", 302 | name: req.body.name, 303 | }); 304 | }); 305 | ``` 306 | 307 | ### [2.11 send and receive from data](https://youtu.be/GXkth_xoG64) 308 | 309 | - create a index.html file inside views folder 310 | 311 | ```html 312 | 313 | 314 | 315 | 316 | home 317 | 318 | 319 | 324 |
325 |

welcome to home page

326 |
327 | 328 | 329 | 330 |
331 |
332 | 333 | 334 | ``` 335 | 336 | - load a html file 337 | 338 | ```js 339 | // Inside user.routes.js file 340 | const express = require("express"); 341 | const path = require("path"); 342 | 343 | const router = express.Router(); 344 | 345 | router.get("/", (req, res) => { 346 | res.sendFile(path.join(__dirname, "../views/index.html")); 347 | }); 348 | 349 | router.post("/", (req, res) => { 350 | res.status(201).json({ 351 | message: "user is created", 352 | name: req.body.name, 353 | }); 354 | }); 355 | 356 | module.exports = router; 357 | 358 | // inside index.js 359 | const express = require("express"); 360 | 361 | const userRoutes = require("./routes/user.routes"); 362 | 363 | const PORT = 3000; 364 | 365 | const app = express(); 366 | 367 | app.use(express.json()); 368 | app.use(express.urlencoded({ extended: true })); 369 | app.use("/users", userRoutes); 370 | 371 | app.listen(PORT, () => { 372 | console.log(`server is running at http://localhost:${PORT}`); 373 | }); 374 | ``` 375 | 376 | ### [2.12 Area Calculator](https://youtu.be/u1BgJg6YzYM) 377 | 378 | ### [2.13 How to set .env variables](https://youtu.be/dxwUjw2Jyfc) 379 | 380 | - Step 1: create an .env file in the root directory 381 | 382 | - Step 2: define environment variable(S) using uppercase letters and underscore if more than one word. Example - 383 | PORT 384 | DATABASE_URL 385 | 386 | - Step 3: Assign the values without double quotation and space 387 | PORT=3000 388 | DATABASE_URL=mongodb+srv://medo:demo1234@cluster0.0tl3q.mongodb.net/test?retryWrites=true&w=majority 389 | 390 | - Step 4: you can make a comment using # 391 | 392 | ```js 393 | # server port 394 | PORT=3000 395 | ``` 396 | 397 | - Step 5: install dotenv package - npm install dotenv 398 | 399 | - Step 6: require dotenv - require('dotenv').config(); 400 | 401 | - Step 7: Access the env variables from anywhere using process.env.VARIABLE_NAME. Example – process.env.PORT; 402 | 403 | - Optional: DotENV Extension - nice syntax highlighting in your .env files. 404 | 405 | ### [2.14 Middlewares](https://youtu.be/byiRZfg2JaE) 406 | 407 | - what is middleware? 408 | - middleware is a function; it contains request obejct, response object and next function 409 | - why middleware? 410 | - execute any code inside middleware 411 | - we can make changes to the request and response object 412 | - we can end the request and response cycle. 413 | - we can call the next middleware in the stack. 414 | - some common usage of middleware 415 | 416 | - user is authenticated or not 417 | - check user is active or not 418 | - data is correct / all data available 419 | 420 | - Types of middleware 421 | 422 | - Application Level middleware: app.use(), app.METHOD(); here METHOD can be get, put, post, delete, patch 423 | - router Level middleware: router.use(),router.METHOD() 424 | - built-in Level middleware: express.json(), express.urlencoded(), express.static() 425 | - third-party Level middleware: body-parser 426 | - error handling middleware 427 | 428 | ```js 429 | // routes not found error 430 | app.use((req, res, next) => { 431 | res.status(404).json({ 432 | message: "resource not found", 433 | }); 434 | }); 435 | 436 | // server error 437 | app.use((err, req, res, next) => { 438 | console.log(err); 439 | res.status(500).json({ 440 | message: "something broke", 441 | }); 442 | }); 443 | ``` 444 | 445 | ### [2.15 express static Middlewares](https://youtu.be/lqRIy6d6D48) 446 | 447 | - `app.use(express.static());` helps us to use static resources such as css and image inside our server 448 | 449 | ### [2.16 MVC Architecture](https://youtu.be/BDeBB9b2L9I) 450 | 451 | - MVC Architecture means Model View Controller Architecture 452 | - Model holds all the database related codes 453 | - View is what users see 454 | - Controller is the connection point between Model and View. basically It deals with all the logic. 455 | - example of mvc file structure: setup a project and install necessary packages ( npm init -y && npm install nodemon express body-parser cors) 456 | 457 | Screenshot 2022-04-26 at 05 13 08 458 | 459 | - controllers - user.controller.js 460 | 461 | ```js 462 | const path = require("path"); 463 | const users = require("../models/user.model"); 464 | 465 | const getUser = (req, res) => { 466 | res.status(200).json({ 467 | users, 468 | }); 469 | }; 470 | 471 | const createUser = (req, res) => { 472 | const user = { 473 | username: req.body.username, 474 | email: req.body.email, 475 | }; 476 | users.push(user); 477 | res.status(201).json(users); 478 | }; 479 | 480 | module.exports = { getUser, createUser }; 481 | ``` 482 | 483 | - models 484 | 485 | - user.model.js 486 | 487 | ```js 488 | const users = [ 489 | { 490 | username: "anisul islam", 491 | email: "lalalal@yahoo.com", 492 | }, 493 | { 494 | username: "rakibul islam", 495 | email: "lalalal@yahoo.com", 496 | }, 497 | ]; 498 | module.exports = users; 499 | ``` 500 | 501 | - routes 502 | 503 | - user.route.js 504 | 505 | ```js 506 | const express = require("express"); 507 | const { getUser, createUser } = require("../controllers/user.controller"); 508 | const router = express.Router(); 509 | 510 | router.get("/", getUser); 511 | router.post("/", createUser); 512 | 513 | module.exports = router; 514 | ``` 515 | 516 | - views 517 | 518 | - index.html 519 | 520 | ```html 521 | 522 | 523 | 524 | 525 | 526 | 527 | Document 528 | 529 | 530 | 536 |

Home Page

537 | 538 | 539 | ``` 540 | 541 | - user.html 542 | 543 | ```html 544 | 545 | 546 | 547 | 548 | 549 | 550 | Document 551 | 552 | 553 | 559 |

User Registration

560 |
561 | 562 | 563 | 564 |
565 | 566 | 567 | ``` 568 | 569 | - .env 570 | - `PORT=4000` 571 | - app.js 572 | 573 | ```js 574 | const express = require("express"); 575 | const cors = require("cors"); 576 | const app = express(); 577 | const bodyParser = require("body-parser"); 578 | const userRouter = require("./routes/user.route"); 579 | // CORS 580 | app.use(bodyParser.urlencoded({ extended: true })); 581 | app.use(bodyParser.json()); 582 | app.use(cors()); 583 | 584 | app.use("/api/users", userRouter); 585 | 586 | app.get("/", (req, res) => { 587 | res.sendFile(__dirname + "/views/index.html"); 588 | }); 589 | 590 | // routes not found error 591 | app.use((req, res, next) => { 592 | res.status(404).json({ 593 | message: "resource not found", 594 | }); 595 | }); 596 | 597 | // server error 598 | app.use((err, req, res, next) => { 599 | console.log(err); 600 | res.status(500).json({ 601 | message: "something broke", 602 | }); 603 | }); 604 | 605 | module.exports = app; 606 | ``` 607 | 608 | - index.js 609 | 610 | ```js 611 | require("dotenv").config(); 612 | const app = require("./app"); 613 | const PORT = process.env.PORT || 5000; 614 | app.listen(PORT, () => { 615 | console.log(`server is running at http://localhost:${PORT}`); 616 | }); 617 | ``` 618 | 619 | ### [2.17] Validation with express-validator 620 | 621 | - install express-validator 622 | 623 | ## Version-2 Express server with a project 624 | 625 | ## Express tutorial 626 | 627 | ## 1. Create an express server 628 | 629 | - initialize npm and install packages 630 | - nodemon montior the changes of our code and update the server 631 | 632 | ```js 633 | npm init -y && npm install express 634 | npm install -D nodemon 635 | ``` 636 | 637 | ```js 638 | // index.js 639 | const express = require("express"); 640 | 641 | const app = express(); 642 | 643 | const port = 3001; 644 | 645 | app.listen(port, () => { 646 | console.log(`server is running at http://localhost:${port}`); 647 | }); 648 | ``` 649 | 650 | ```json 651 | //package.json 652 | "scripts": { 653 | "test": "echo \"Error: no test specified\" && exit 1", 654 | "start": "node src/index.js", 655 | "start-dev": "nodemon src/index.js" 656 | }, 657 | ``` 658 | 659 | ## 2. setting environment variables 660 | 661 | ## 3. Handle GET Request -> GET all products 662 | 663 | - routing plan using HTTP methods for RESTful Services 664 | - HTTP Verbs -> GET, POST, PUT, PATCH, DELETE helps us to CRUD operations 665 | 666 | ```js 667 | GET /products - get all the products -> 200 (ok) / 404 (not found) 668 | GET /products/:id - get a single product -> 200 / 404 669 | POST /products/ - create a single product -> 201 (Created) / 404 (Not Found) / 409 (Conflict -> Already Exist) 670 | PUT /products/:id - update/replace every resource in a single product -> 200 (Ok) / 404 (Not Found) / 405 (Method Not Allowed) 671 | PATCH /products/:id - update/Modify product itself -> 200 (Ok) / 404 (Not Found) / 405 (Method Not Allowed) 672 | DELETE /products/:id - delete a single product -> 200 (Ok) / 404 (Not Found) / 405 (Method Not Allowed) 673 | 674 | ``` 675 | 676 | ```js 677 | // app.use() 678 | app.use("/", (req, res) => { 679 | res.send("home page"); 680 | }); 681 | 682 | // now use ThunderClient extension for testing the API; you will see app.use() accept all http methods 683 | 684 | // app.get() - will only accept get method 685 | app.get("/", (req, res) => { 686 | res.send("home page"); 687 | }); 688 | ``` 689 | 690 | ```js 691 | let products = [ 692 | { 693 | id: 1, 694 | title: "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops", 695 | price: 109.95, 696 | }, 697 | { 698 | id: 2, 699 | title: "Mens Casual Premium Slim Fit T-Shirts ", 700 | price: 22.3, 701 | }, 702 | ]; 703 | 704 | app.get("/products", (req, res) => { 705 | res.send(products); 706 | }); 707 | ``` 708 | 709 | ## 4. Middleware 710 | 711 | ## 5. Handling error 712 | 713 | ```js 714 | // client error 715 | app.use((req, res) => { 716 | res.send("

Page not found 404

"); 717 | }); 718 | 719 | // server error 720 | app.use((err, req, res, next) => { 721 | console.error(err.stack); 722 | res.send("Something broke!"); 723 | }); 724 | ``` 725 | 726 | ## 6. Response Object 727 | 728 | - text, HTML, JSON 729 | 730 | ```js 731 | res.send("hello"); 732 | res.send({ 733 | success: true, 734 | user: { id: 1, name: "anisul" }, 735 | }); 736 | res.sendFile("hello.html"); 737 | ``` 738 | 739 | ## 7. [Status codes](https://devhints.io/http-status) 740 | 741 | ```js 742 | app.get("/", (req, res) => { 743 | res.status(200).send("home page"); 744 | }); 745 | 746 | app.get("/products", (req, res) => { 747 | res.status(200).send(products); 748 | }); 749 | 750 | app.use((req, res) => { 751 | res.status(404).send("

Page not found 404

"); 752 | }); 753 | 754 | app.use((err, req, res, next) => { 755 | console.error(err.stack); 756 | res.status(500).send("Something broke!"); 757 | }); 758 | ``` 759 | 760 | ## 8. Request Object 761 | 762 | - request with query parameter - req.query.parameterName 763 | 764 | - request with route parameters - req.params.parameterName 765 | 766 | - request with headers - req.header(key) 767 | 768 | - request with json data / form data inside body - req.body.parameterName 769 | 770 | - query parameter has question mark; search something on google. 771 | 772 | - example of query parameter - http://localhost:3000?id=101&name=anisul islam 773 | 774 | - we can get the value using req.query.id and req.query.name 775 | 776 | ```js 777 | router.post("/", (req, res) => { 778 | console.log(req.query); 779 | console.log(req.query.id); 780 | console.log(req.query.name); 781 | res.send("I am get method of user route"); 782 | }); 783 | ``` 784 | 785 | ## 9. Handle GET Request -> get a single product 786 | 787 | ```js 788 | // route parameter 789 | app.get("/products/:id", (req, res) => { 790 | const singleProduct = products.find( 791 | (product) => product.id === Number(req.params.id) 792 | ); 793 | res.status(200).send(singleProduct); 794 | }); 795 | 796 | // query parameter 797 | const sortItems = (sortBy, items) => { 798 | if (sortBy === "ASC") { 799 | return items.sort((a, b) => a.price - b.price); 800 | } else if (sortBy === "DESC") { 801 | return items.sort((a, b) => b.price - a.price); 802 | } 803 | }; 804 | 805 | const sortItems = (sortBy, items) => { 806 | if (sortBy === "ASC") { 807 | return items.sort((a, b) => a.price - b.price); 808 | } else if (sortBy === "DESC") { 809 | return items.sort((a, b) => b.price - a.price); 810 | } 811 | }; 812 | 813 | app.get("/products", (req, res) => { 814 | const maxPrice = Number(req.query.maxPrice); 815 | const sortBy = req.query.sortBy; 816 | let result; 817 | if (maxPrice) { 818 | result = products.filter((product) => product.price <= maxPrice); 819 | result = sortBy ? sortItems(sortBy, result) : result; 820 | res.status(200).send(result); 821 | } else { 822 | res.status(200).send(products); 823 | } 824 | }); 825 | ``` 826 | 827 | ## 10. Handle POST Request -> create a single product 828 | 829 | ```js 830 | app.use(express.json()); 831 | app.use(express.urlencoded({ extended: true })); 832 | 833 | app.post("/products", (req, res) => { 834 | const newProduct = { 835 | id: Number(req.body.id), 836 | title: req.body.title, 837 | price: req.body.price, 838 | }; 839 | products.push(newProduct); 840 | res.status(200).send(newProduct); 841 | }); 842 | ``` 843 | 844 | ## 11. Handle DELETE Request -> delete a single product 845 | 846 | ```js 847 | app.delete("/products/:id", (req, res) => { 848 | products = products.filter((product) => product.id !== Number(req.params.id)); 849 | res.status(200).send(products); 850 | }); 851 | ``` 852 | 853 | ## 12. Handle PUT Request -> update a single product 854 | 855 | ```js 856 | app.put("/products/:id", (req, res) => { 857 | products 858 | .filter((product) => product.id === Number(req.params.id)) 859 | .map((product) => { 860 | product.title = req.body.title; 861 | product.price = req.body.price; 862 | }); 863 | res.status(200).send(products); 864 | }); 865 | ``` 866 | 867 | ## 13. MVC Structure - Routing with express Router 868 | 869 | - Separation of Concerns 870 | - Model, View, Controllers 871 | - create a router folder and then create a product file where we will move all our routes 872 | 873 | ```js 874 | //routes -> product.js 875 | const express = require("express"); 876 | const router = express.Router(); 877 | 878 | let products = [ 879 | { 880 | id: 1, 881 | title: "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops", 882 | price: 109.95, 883 | }, 884 | { 885 | id: 2, 886 | title: "Mens Casual Premium Slim Fit T-Shirts ", 887 | price: 22.3, 888 | }, 889 | { 890 | id: 3, 891 | title: "Mens Cotton Jacket", 892 | price: 55.99, 893 | }, 894 | { id: 4, title: "Mens Casual Slim Fit", price: 15.99 }, 895 | ]; 896 | 897 | const sortItems = (sortBy, items) => { 898 | if (sortBy === "ASC") { 899 | return items.sort((a, b) => a.price - b.price); 900 | } else if (sortBy === "DESC") { 901 | return items.sort((a, b) => b.price - a.price); 902 | } 903 | }; 904 | 905 | router.get("/products", (req, res) => { 906 | const maxPrice = Number(req.query.maxPrice); 907 | const sortBy = req.query.sortBy; 908 | let result; 909 | if (maxPrice) { 910 | result = products.filter((product) => product.price <= maxPrice); 911 | result = sortBy ? sortItems(sortBy, result) : result; 912 | res.status(200).send(result); 913 | } else { 914 | res.status(200).send(products); 915 | } 916 | }); 917 | 918 | router.get("/products/:id", (req, res) => { 919 | const singleProduct = products.find( 920 | (product) => product.id === Number(req.params.id) 921 | ); 922 | res.status(200).send(singleProduct); 923 | }); 924 | 925 | router.post("/products", (req, res) => { 926 | const newProduct = { 927 | id: Number(req.body.id), 928 | title: req.body.title, 929 | price: req.body.price, 930 | }; 931 | products.push(newProduct); 932 | res.status(200).send(newProduct); 933 | }); 934 | 935 | router.put("/products/:id", (req, res) => { 936 | products 937 | .filter((product) => product.id === Number(req.params.id)) 938 | .map((product) => { 939 | product.title = req.body.title; 940 | product.price = req.body.price; 941 | }); 942 | res.status(200).send(products); 943 | }); 944 | 945 | router.delete("/products/:id", (req, res) => { 946 | products = products.filter((product) => product.id !== Number(req.params.id)); 947 | res.status(200).send(products); 948 | }); 949 | 950 | module.exports = router; 951 | 952 | // inside index.js 953 | const productRouters = require("./router/products"); 954 | app.use(productRouters); 955 | ``` 956 | 957 | - remove all the products and in index.js use `app.use("/products", productRouters);` 958 | 959 | ## 14. MVC Structure - Controller part 960 | 961 | ```js 962 | // routes -> products.js 963 | const express = require("express"); 964 | const { 965 | getAllProducts, 966 | getSingleProduct, 967 | createProduct, 968 | updateProduct, 969 | deleteProduct, 970 | } = require("../controller/products"); 971 | const router = express.Router(); 972 | 973 | router.get("/", getAllProducts).get("/:id", getSingleProduct); 974 | 975 | router.post("/", createProduct); 976 | 977 | router.put("/:id", updateProduct); 978 | 979 | router.delete("/:id", deleteProduct); 980 | 981 | module.exports = router; 982 | 983 | // controller -> products.js 984 | let products = [ 985 | { 986 | id: 1, 987 | title: "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops", 988 | price: 109.95, 989 | }, 990 | { 991 | id: 2, 992 | title: "Mens Casual Premium Slim Fit T-Shirts ", 993 | price: 22.3, 994 | }, 995 | { 996 | id: 3, 997 | title: "Mens Cotton Jacket", 998 | price: 55.99, 999 | }, 1000 | { id: 4, title: "Mens Casual Slim Fit", price: 15.99 }, 1001 | ]; 1002 | 1003 | const sortItems = (sortBy, items) => { 1004 | if (sortBy === "ASC") { 1005 | return items.sort((a, b) => a.price - b.price); 1006 | } else if (sortBy === "DESC") { 1007 | return items.sort((a, b) => b.price - a.price); 1008 | } 1009 | }; 1010 | 1011 | const getAllProducts = (req, res) => { 1012 | const maxPrice = Number(req.query.maxPrice); 1013 | const sortBy = req.query.sortBy; 1014 | let result; 1015 | if (maxPrice) { 1016 | result = products.filter((product) => product.price <= maxPrice); 1017 | result = sortBy ? sortItems(sortBy, result) : result; 1018 | res.status(200).send(result); 1019 | } else { 1020 | res.status(200).send(products); 1021 | } 1022 | }; 1023 | 1024 | const getSingleProduct = (req, res) => { 1025 | const singleProduct = products.find( 1026 | (product) => product.id === Number(req.params.id) 1027 | ); 1028 | res.status(200).send(singleProduct); 1029 | }; 1030 | 1031 | const createProduct = (req, res) => { 1032 | const newProduct = { 1033 | id: Number(req.body.id), 1034 | title: req.body.title, 1035 | price: req.body.price, 1036 | }; 1037 | products.push(newProduct); 1038 | res.status(200).send(newProduct); 1039 | }; 1040 | 1041 | const updateProduct = (req, res) => { 1042 | products 1043 | .filter((product) => product.id === Number(req.params.id)) 1044 | .map((product) => { 1045 | product.title = req.body.title; 1046 | product.price = req.body.price; 1047 | }); 1048 | res.status(200).send(products); 1049 | }; 1050 | 1051 | const deleteProduct = (req, res) => { 1052 | products = products.filter((product) => product.id !== Number(req.params.id)); 1053 | res.status(200).send(products); 1054 | }; 1055 | 1056 | module.exports = { 1057 | getAllProducts, 1058 | getSingleProduct, 1059 | createProduct, 1060 | updateProduct, 1061 | deleteProduct, 1062 | }; 1063 | ``` 1064 | 1065 | ## 15. MVC Structure - Model part 1066 | 1067 | ```js 1068 | // model -> products.js 1069 | let products = [ 1070 | { 1071 | id: 1, 1072 | title: "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops", 1073 | price: 109.95, 1074 | }, 1075 | { 1076 | id: 2, 1077 | title: "Mens Casual Premium Slim Fit T-Shirts ", 1078 | price: 22.3, 1079 | }, 1080 | { 1081 | id: 3, 1082 | title: "Mens Cotton Jacket", 1083 | price: 55.99, 1084 | }, 1085 | { id: 4, title: "Mens Casual Slim Fit", price: 15.99 }, 1086 | ]; 1087 | 1088 | module.exports = products; 1089 | ``` 1090 | 1091 | ## 15. EJS 1092 | 1093 | ## 16. Deploy on Heroku 1094 | 1095 | - `const port = process.env.PORT || 3001;` 1096 | - Procfile -> `web: node index.js` 1097 | - add .gitignore file -> `node_modules_` 1098 | 1099 | ## 17. Database 1100 | 1101 | - save(), find(), findOne(), deleteOne(), updateOne() 1102 | 1103 | ```js 1104 | const mongoose = require("mongoose"); 1105 | mongoose 1106 | .connect("mongodb://localhost:27017/testProduct") 1107 | .then(() => console.log("DB is connected")) 1108 | .catch((error) => { 1109 | console.log(error.message); 1110 | process.exit(1); 1111 | }); 1112 | 1113 | // schema & model 1114 | const { model } = require("mongoose"); 1115 | const mongoose = require("mongoose"); 1116 | 1117 | const productsSchema = new mongoose.Schema({ 1118 | id: Number, 1119 | title: String, 1120 | price: Number, 1121 | }); 1122 | 1123 | module.exports = model("Product", productsSchema); 1124 | 1125 | // controller 1126 | const Products = require("../model/products"); 1127 | 1128 | // Create 1129 | const createProduct = async (req, res) => { 1130 | try { 1131 | const newProduct = new Products({ 1132 | id: Number(req.body.id), 1133 | title: req.body.title, 1134 | price: req.body.price, 1135 | }); 1136 | await newProduct.save(); 1137 | res.status(200).send(newProduct); 1138 | } catch (error) { 1139 | res.status(500).send(error.message); 1140 | } 1141 | }; 1142 | 1143 | // Read 1144 | const getAllProducts = async (req, res) => { 1145 | try { 1146 | const products = await Products.find(); 1147 | res.status(200).send(products); 1148 | } catch (error) { 1149 | res.status(500).send(error.message); 1150 | } 1151 | }; 1152 | 1153 | // read all the products 1154 | const getAllProducts = async (req, res) => { 1155 | try { 1156 | const products = await Products.find(); 1157 | const maxPrice = Number(req.query.maxPrice); 1158 | const sortBy = req.query.sortBy; 1159 | let result; 1160 | if (maxPrice) { 1161 | result = await Products.find({ price: { $lt: maxPrice } }); 1162 | result = sortBy ? sortItems(sortBy, result) : result; 1163 | res.status(200).send(result); 1164 | } else { 1165 | res.status(200).send(products); 1166 | } 1167 | } catch (error) { 1168 | res.status(500).send(error.message); 1169 | } 1170 | }; 1171 | 1172 | // read single product by id 1173 | const getSingleProduct = async (req, res) => { 1174 | try { 1175 | // const id = parseInt(req.params.id); 1176 | const singleProduct = await Products.findOne({ req.params.id }); 1177 | res.status(200).send(singleProduct); 1178 | } catch (error) { 1179 | res.status(500).send(error.message); 1180 | } 1181 | }; 1182 | 1183 | // delete one product by id 1184 | const deleteProduct = async (req, res) => { 1185 | try { 1186 | const id = parseInt(req.params.id); 1187 | const singleProduct = await Products.deleteOne({ id }); 1188 | res.status(200).send({ success: true }); 1189 | } catch (error) { 1190 | res.status(500).send(error.message); 1191 | } 1192 | }; 1193 | 1194 | // update a product by id 1195 | const updateProduct = async (req, res) => { 1196 | try { 1197 | await Products.updateOne( 1198 | { id: req.params.id }, 1199 | { 1200 | $set: { 1201 | title: req.body.title, 1202 | price: req.body.price, 1203 | }, 1204 | } 1205 | ); 1206 | res.status(200).send({ success: true }); 1207 | } catch (error) { 1208 | res.status(500).send(error.message); 1209 | } 1210 | }; 1211 | ``` 1212 | 1213 | ## 18. cors setup 1214 | 1215 | - cors setup 1216 | 1217 | ```js 1218 | npm install cors 1219 | app.use(cors()) 1220 | ``` 1221 | 1222 | ## 19. connection from front end 1223 | 1224 | ```js 1225 | import "./App.css"; 1226 | import React, { useEffect, useState } from "react"; 1227 | import NewProduct from "./components/NewProduct"; 1228 | 1229 | const URL = "http://localhost:4000/products"; 1230 | function App() { 1231 | const [products, setProducts] = useState([]); 1232 | const [isLoading, setIsLoading] = useState(true); 1233 | const [error, setError] = useState(null); 1234 | 1235 | // update 1236 | const [selectedProduct, setSelectedProduct] = useState({ 1237 | title: "", 1238 | price: "", 1239 | }); 1240 | const [updateFlag, setUpdateFlag] = useState(false); 1241 | const [selectedProductId, setSelectedProductId] = useState(""); 1242 | 1243 | const getAllProducts = () => { 1244 | fetch(URL) 1245 | .then((res) => { 1246 | if (!res.ok) { 1247 | throw Error("could not fetch"); 1248 | } 1249 | return res.json(); 1250 | }) 1251 | .then((result) => { 1252 | setProducts(result); 1253 | }) 1254 | .catch((err) => { 1255 | setError(err.message); 1256 | }) 1257 | .finally(() => { 1258 | setIsLoading(false); 1259 | }); 1260 | }; 1261 | useEffect(() => { 1262 | getAllProducts(); 1263 | }, []); 1264 | 1265 | const handleDelete = (id) => { 1266 | fetch(URL + `${id}`, { 1267 | method: "DELETE", 1268 | }) 1269 | .then((res) => { 1270 | if (!res.ok) { 1271 | throw Error("could not delete"); 1272 | } 1273 | getAllProducts(); 1274 | }) 1275 | .catch((err) => { 1276 | setError(err.message); 1277 | }); 1278 | }; 1279 | 1280 | const addProduct = (product) => { 1281 | fetch(URL, { 1282 | method: "POST", 1283 | headers: { 1284 | "Content-Type": "application/json", 1285 | }, 1286 | body: JSON.stringify(product), 1287 | }) 1288 | .then((res) => { 1289 | if (res.status === 201) { 1290 | getAllProducts(); 1291 | } else { 1292 | throw new Error("could not create new product"); 1293 | } 1294 | }) 1295 | .catch((err) => { 1296 | setError(err.message); 1297 | }); 1298 | }; 1299 | 1300 | const handleEdit = (id) => { 1301 | setSelectedProductId(id); 1302 | setUpdateFlag(true); 1303 | const filteredData = products.filter((product) => product.id === id); 1304 | setSelectedProduct({ 1305 | title: filteredData[0].title, 1306 | price: filteredData[0].price, 1307 | }); 1308 | }; 1309 | 1310 | const handleUpdate = (product) => { 1311 | console.log(selectedProductId); 1312 | fetch(URL + `/${selectedProductId}`, { 1313 | method: "PUT", 1314 | headers: { 1315 | "Content-Type": "application/json", 1316 | }, 1317 | body: JSON.stringify(product), 1318 | }) 1319 | .then((res) => { 1320 | if (!res.ok) { 1321 | throw new Error("failed to update"); 1322 | } 1323 | getAllProducts(); 1324 | setUpdateFlag(false); 1325 | }) 1326 | .catch((err) => { 1327 | setError(err.message); 1328 | }); 1329 | }; 1330 | 1331 | return ( 1332 |
1333 |

Products

1334 | {isLoading &&

Loading...

} 1335 | {error &&

{error}

} 1336 | 1337 | {updateFlag ? ( 1338 | 1343 | ) : ( 1344 | 1345 | )} 1346 | 1347 | {products.length > 0 && 1348 | products.map((product) => ( 1349 |
1350 |

{product.title}

1351 |

{product.price}

1352 | 1359 | 1366 |
1367 | ))} 1368 |
1369 | ); 1370 | } 1371 | 1372 | export default App; 1373 | 1374 | 1375 | // NewProduct.js 1376 | import React, { useState, useEffect } from "react"; 1377 | import { v4 as uuidv4 } from "uuid"; 1378 | 1379 | const NewProduct = ({ handleSubmitData, selectedProduct, btnText }) => { 1380 | const [product, setProduct] = useState({ 1381 | title: "", 1382 | price: "", 1383 | }); 1384 | 1385 | const { title, price } = product; 1386 | 1387 | useEffect(() => { 1388 | setProduct({ 1389 | title: selectedProduct.title, 1390 | price: selectedProduct.price, 1391 | }); 1392 | }, [selectedProduct]); 1393 | 1394 | const handleChange = (e) => { 1395 | const selectedField = e.target.name; 1396 | const selectedValue = e.target.value; 1397 | setProduct((prevState) => { 1398 | return { ...prevState, [selectedField]: selectedValue }; 1399 | }); 1400 | }; 1401 | 1402 | const handleSubmit = (e) => { 1403 | e.preventDefault(); 1404 | const newProduct = { 1405 | id: Number(uuidv4()), 1406 | title: product.title, 1407 | price: product.price, 1408 | }; 1409 | handleSubmitData(newProduct); 1410 | setProduct({ 1411 | title: "", 1412 | price: "", 1413 | }); 1414 | }; 1415 | 1416 | return ( 1417 |
1418 |
1419 | 1420 | 1428 |
1429 |
1430 | 1431 | 1439 |
1440 | 1443 |
1444 | ); 1445 | }; 1446 | 1447 | NewProduct.defaultProps = { 1448 | selectedProduct: { 1449 | title: "", 1450 | price: "", 1451 | }, 1452 | }; 1453 | 1454 | export default NewProduct; 1455 | 1456 | ``` 1457 | 1458 | ## CORS Setup 1459 | 1460 | ## REST API 1461 | 1462 | - basically we are going to return some data 1463 | - Reperesentational State Transfer 1464 | - Response data -> text, html, xml, json 1465 | - HTTP methods -> GET, POST, PUT (CREATE/OVERRIDE A RESOURCE) /PATCH, DELETE 1466 | - Routing 1467 | 1468 | ## Updating 1469 | 1470 | ### Lecture 1 - Course plan 1471 | 1472 | ### Lecture 2 - basic setup 1473 | 1474 | - Node.js installation and version checkup 1475 | - typescript, ts-node 1476 | - nodemon : rsestart server after file changing in server 1477 | - postman / insomnia 1478 | - mongodb 1479 | --------------------------------------------------------------------------------