└── 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 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------