From 64d26af4256cff9cf116f7721b1b3c6b00326743 Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 18 Nov 2025 21:08:32 -0800 Subject: [PATCH 1/7] answers for lesson 1 --- 01-node-tutorial/answers/01-intro.js | 8 +++ 01-node-tutorial/answers/02-global.js | 2 + 01-node-tutorial/answers/03-modules.js | 7 +++ 01-node-tutorial/answers/04-names.js | 6 ++ 01-node-tutorial/answers/05-utils.js | 5 ++ .../answers/06-alternative-flavor.js | 6 ++ 01-node-tutorial/answers/07-mind-grenade.js | 5 ++ 01-node-tutorial/answers/08-os-module.js | 3 + 01-node-tutorial/answers/09-path-module.js | 4 ++ 01-node-tutorial/answers/10-fs-sync.js | 15 +++++ 01-node-tutorial/answers/11-fs-async.js | 29 ++++++++++ 01-node-tutorial/answers/12-http.js | 18 ++++++ 01-node-tutorial/answers/prompter.js | 57 ++++++++++++++----- 13 files changed, 150 insertions(+), 15 deletions(-) create mode 100644 01-node-tutorial/answers/01-intro.js create mode 100644 01-node-tutorial/answers/02-global.js create mode 100644 01-node-tutorial/answers/03-modules.js create mode 100644 01-node-tutorial/answers/04-names.js create mode 100644 01-node-tutorial/answers/05-utils.js create mode 100644 01-node-tutorial/answers/06-alternative-flavor.js create mode 100644 01-node-tutorial/answers/07-mind-grenade.js create mode 100644 01-node-tutorial/answers/08-os-module.js create mode 100644 01-node-tutorial/answers/09-path-module.js create mode 100644 01-node-tutorial/answers/10-fs-sync.js create mode 100644 01-node-tutorial/answers/11-fs-async.js create mode 100644 01-node-tutorial/answers/12-http.js diff --git a/01-node-tutorial/answers/01-intro.js b/01-node-tutorial/answers/01-intro.js new file mode 100644 index 0000000000..342dddc01f --- /dev/null +++ b/01-node-tutorial/answers/01-intro.js @@ -0,0 +1,8 @@ +const amount = 9 + +if (amount < 10) { + console.log('small number') +} else { + console.log('large number') +} + diff --git a/01-node-tutorial/answers/02-global.js b/01-node-tutorial/answers/02-global.js new file mode 100644 index 0000000000..6b29a22fec --- /dev/null +++ b/01-node-tutorial/answers/02-global.js @@ -0,0 +1,2 @@ +console.log(__dirname); +console.log(process.env.MY_VAR); diff --git a/01-node-tutorial/answers/03-modules.js b/01-node-tutorial/answers/03-modules.js new file mode 100644 index 0000000000..2816f541ec --- /dev/null +++ b/01-node-tutorial/answers/03-modules.js @@ -0,0 +1,7 @@ +const names = require("./04-names.js"); +const fullname = require("./05-utils.js") +const alt = require("./06-alternative-flavor.js") +const activate = require("./07-mind-grenade.js") + +fullname(names.carl, names.carl_lastname) +console.log(`Hello my name is ${alt.singlePerson.name} my favorite foods are ${alt.favoriteFood[0]} and ${alt.favoriteFood[1]}!`) \ No newline at end of file diff --git a/01-node-tutorial/answers/04-names.js b/01-node-tutorial/answers/04-names.js new file mode 100644 index 0000000000..ede7162e5e --- /dev/null +++ b/01-node-tutorial/answers/04-names.js @@ -0,0 +1,6 @@ +const carl = 'Carl' +const carl_lastname = 'Balansag' +const random_name = 'Jake' +const random_name_lastname = 'Smith' + +module.exports = { carl, carl_lastname, random_name, random_name_lastname } \ No newline at end of file diff --git a/01-node-tutorial/answers/05-utils.js b/01-node-tutorial/answers/05-utils.js new file mode 100644 index 0000000000..50526abbde --- /dev/null +++ b/01-node-tutorial/answers/05-utils.js @@ -0,0 +1,5 @@ +const fullname = (first, last) => { + console.log(`Hello my full name is ${first} ${last}`) +} + +module.exports = fullname diff --git a/01-node-tutorial/answers/06-alternative-flavor.js b/01-node-tutorial/answers/06-alternative-flavor.js new file mode 100644 index 0000000000..a5d84a5de5 --- /dev/null +++ b/01-node-tutorial/answers/06-alternative-flavor.js @@ -0,0 +1,6 @@ +module.exports.favoriteFood = ['Steak', 'Cheese'] +const person = { + name: 'Jack', +} + +module.exports.singlePerson = person diff --git a/01-node-tutorial/answers/07-mind-grenade.js b/01-node-tutorial/answers/07-mind-grenade.js new file mode 100644 index 0000000000..e780dd7256 --- /dev/null +++ b/01-node-tutorial/answers/07-mind-grenade.js @@ -0,0 +1,5 @@ +function activate(name, food1, food2) { + console.log(`This was activated from another file`) +} + +activate() \ No newline at end of file diff --git a/01-node-tutorial/answers/08-os-module.js b/01-node-tutorial/answers/08-os-module.js new file mode 100644 index 0000000000..b69be937e8 --- /dev/null +++ b/01-node-tutorial/answers/08-os-module.js @@ -0,0 +1,3 @@ +const os = require("os"); + +console.log(os) \ No newline at end of file diff --git a/01-node-tutorial/answers/09-path-module.js b/01-node-tutorial/answers/09-path-module.js new file mode 100644 index 0000000000..3cf8a571f9 --- /dev/null +++ b/01-node-tutorial/answers/09-path-module.js @@ -0,0 +1,4 @@ +const path = require('path') + +const filePath = path.join('folder1', 'folder2', 'folder3', 'file.txt') +console.log(filePath) \ No newline at end of file diff --git a/01-node-tutorial/answers/10-fs-sync.js b/01-node-tutorial/answers/10-fs-sync.js new file mode 100644 index 0000000000..7644b5c484 --- /dev/null +++ b/01-node-tutorial/answers/10-fs-sync.js @@ -0,0 +1,15 @@ +const { writeFileSync, readFileSync } = require('fs') + +//Creates the file (or overwrites if it exists) +writeFileSync('./temporary/fileA.txt', 'This is line 1\n') + +//Append flag adds to the file +writeFileSync('./temporary/fileA.txt', 'This is line 2\n', { flag: 'a' }) + +//Apend flag adds to the file +writeFileSync('./temporary/fileA.txt', 'This is line 3\n', { flag: 'a' }) + +//Read the file +const content = readFileSync('./temporary/fileA.txt', 'utf8') + +console.log(content) \ No newline at end of file diff --git a/01-node-tutorial/answers/11-fs-async.js b/01-node-tutorial/answers/11-fs-async.js new file mode 100644 index 0000000000..3aacdb4fd7 --- /dev/null +++ b/01-node-tutorial/answers/11-fs-async.js @@ -0,0 +1,29 @@ +const { writeFile } = require("fs"); +console.log("at start"); +writeFile("./temporary/fileB.txt", "This is line 1\n", (err, result) => { + console.log("at point 1"); + if (err) { + console.log("This error happened: ", err); + } else { + //Write line 2 inside this callback + writeFile("./temporary/fileB.txt", "This is line 2\n", { flag: "a" }, (err, result) => { + console.log("at point 2"); + if (err) { + console.log("This error happened: ", err); + } else { + //Write line 3 inside this callback + writeFile("./temporary/fileB.txt", "This is line 3\n", { flag: "a" }, (err, result) => { + console.log("at point 3"); + if (err) { + console.log("This error happened: ", err); + } else { + //Everything worked write completed + console.log("File writing complete!"); + } + }); + } + }); + } +}); + +console.log("at end"); \ No newline at end of file diff --git a/01-node-tutorial/answers/12-http.js b/01-node-tutorial/answers/12-http.js new file mode 100644 index 0000000000..32d974e0e0 --- /dev/null +++ b/01-node-tutorial/answers/12-http.js @@ -0,0 +1,18 @@ +const http = require('http') + +const server = http.createServer((req, res) => { + if (req.url === '/') { + res.end('This is the the home page') + } else if (req.url === '/about') { + res.end('This is the about page') + } else { + res.end(` +

ERROR!

+

PAGE YOU ARE LOOKING FOR DOESN'T EXIST

+ back home + `) + } +}) + +server.listen(3000) +console.log('Server is listening on port 3000...') \ No newline at end of file diff --git a/01-node-tutorial/answers/prompter.js b/01-node-tutorial/answers/prompter.js index 38e93d8311..a781e236f7 100644 --- a/01-node-tutorial/answers/prompter.js +++ b/01-node-tutorial/answers/prompter.js @@ -20,19 +20,24 @@ const getBody = (req, callback) => { }); }; -// here, you could declare one or more variables to store what comes back from the form. -let item = "Enter something below."; +//Generate a random secret number between 1 and 100 +let secretNumber = Math.floor(Math.random() * 100) + 1; +let message = "Guess the number between 1 and 100."; +let attempts = 0; -// here, you can change the form below to modify the input fields and what is displayed. -// This is just ordinary html with string interpolation. const form = () => { return ` -

${item}

-
- - -
+

Number Guessing Game

+

${message}

+

Attempts: ${attempts}

+
+ + +
+
+ +
`; }; @@ -43,13 +48,35 @@ const server = http.createServer((req, res) => { if (req.method === "POST") { getBody(req, (body) => { console.log("The body of the post is ", body); - // here, you can add your own logic - if (body["item"]) { - item = body["item"]; + + // Check if user wants to reset the game + if (body["reset"]) { + secretNumber = Math.floor(Math.random() * 100) + 1; + message = "New game started! Guess the number between 1 and 100."; + attempts = 0; + console.log(`New secret number generated: ${secretNumber}`); + } + // Process the guess + else if (body["guess"]) { + const guess = parseInt(body["guess"]); + attempts++; + + console.log(`Player guessed: ${guess}, Secret number: ${secretNumber}, Attempts: ${attempts}`); + + if (isNaN(guess)) { + message = "Please enter a valid number!"; + } else if (guess === secretNumber) { + message = `Congratulations! You guessed it in ${attempts} attempts! The number was ${secretNumber}.`; + console.log(`Player won in ${attempts} attempts!`); + } else if (guess < secretNumber) { + message = `Too low! Try again. (Attempt ${attempts})`; + } else { + message = `Too high! Try again. (Attempt ${attempts})`; + } } else { - item = "Nothing was entered."; + message = "Please enter a guess!"; } - // Your code changes would end here + res.writeHead(303, { Location: "/", }); @@ -61,4 +88,4 @@ const server = http.createServer((req, res) => { }); server.listen(3000); -console.log("The server is listening on port 3000."); +console.log("The server is listening on port 3000."); \ No newline at end of file From 44333b9d2f350fbdd6bac30d43a052c2e2bc6185 Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 25 Nov 2025 06:29:52 -0800 Subject: [PATCH 2/7] week 2 --- 01-node-tutorial/answers/.gitignore | 5 ++++ 01-node-tutorial/answers/16-streams.js | 21 ++++++++++++++ 01-node-tutorial/answers/customEmitter.js | 22 +++++++++++++++ 01-node-tutorial/answers/prompter.js | 3 ++ .../answers/writeWithPromisesThen.js | 18 ++++++++++++ .../answers/writeWithpromisesAwait.js | 28 +++++++++++++++++++ 6 files changed, 97 insertions(+) create mode 100644 01-node-tutorial/answers/.gitignore create mode 100644 01-node-tutorial/answers/16-streams.js create mode 100644 01-node-tutorial/answers/customEmitter.js create mode 100644 01-node-tutorial/answers/writeWithPromisesThen.js create mode 100644 01-node-tutorial/answers/writeWithpromisesAwait.js diff --git a/01-node-tutorial/answers/.gitignore b/01-node-tutorial/answers/.gitignore new file mode 100644 index 0000000000..7deb6da238 --- /dev/null +++ b/01-node-tutorial/answers/.gitignore @@ -0,0 +1,5 @@ +/node_modules + +.DS_Store + +temp.txt \ No newline at end of file diff --git a/01-node-tutorial/answers/16-streams.js b/01-node-tutorial/answers/16-streams.js new file mode 100644 index 0000000000..b3161e7c4b --- /dev/null +++ b/01-node-tutorial/answers/16-streams.js @@ -0,0 +1,21 @@ +const { createReadStream } = require('fs'); + +const stream = createReadStream('../content/big.txt', { + encoding: 'utf8', + highWaterMark: 200 +}); + +let counter = 0; + +stream.on('data', (result) => { + counter++; + console.log(`Chunk ${counter}:`, result); +}); + +stream.on('end', () => { + console.log(`\nStream ended. Total chunks received: ${counter}`); +}); + +stream.on('error', (error) => { + console.error('Error reading stream:', error); +}); diff --git a/01-node-tutorial/answers/customEmitter.js b/01-node-tutorial/answers/customEmitter.js new file mode 100644 index 0000000000..7edd273233 --- /dev/null +++ b/01-node-tutorial/answers/customEmitter.js @@ -0,0 +1,22 @@ +const EventEmitter = require("events"); + +// Create an emitter +const emitter = new EventEmitter(); + +// Set up event handlers +emitter.on("greeting", (name) => { + console.log(`Hello, ${name}!`); +}); + +emitter.on("timer", (msg) => { + console.log(msg); +}); + +// Emit some events +emitter.emit("greeting", "Tom"); +emitter.emit("greeting", "Bob"); + +// Set up a timer that emits events every 2 seconds +setInterval(() => { + emitter.emit("timer", "Timer event triggered"); +}, 2000); diff --git a/01-node-tutorial/answers/prompter.js b/01-node-tutorial/answers/prompter.js index a781e236f7..ff8859a29c 100644 --- a/01-node-tutorial/answers/prompter.js +++ b/01-node-tutorial/answers/prompter.js @@ -87,5 +87,8 @@ const server = http.createServer((req, res) => { } }); +server.on("request", (req) => { + console.log("event received: ", req.method, req.url); +}); server.listen(3000); console.log("The server is listening on port 3000."); \ No newline at end of file diff --git a/01-node-tutorial/answers/writeWithPromisesThen.js b/01-node-tutorial/answers/writeWithPromisesThen.js new file mode 100644 index 0000000000..4ae09935a5 --- /dev/null +++ b/01-node-tutorial/answers/writeWithPromisesThen.js @@ -0,0 +1,18 @@ +const { writeFile, readFile } = require("fs").promises; + +writeFile('./temporary/temp.txt', 'This is line 1\n') + .then(() => { + return writeFile('./temporary/temp.txt', 'This is line 2\n', { flag: 'a' }); + }) + .then(() => { + return writeFile('./temporary/temp.txt', 'This is line 3\n', { flag: 'a' }); + }) + .then(() => { + return readFile('./temporary/temp.txt', 'utf8'); + }) + .then((data) => { + console.log(data); + }) + .catch((error) => { + console.log("An error occurred: ", error); + }); diff --git a/01-node-tutorial/answers/writeWithpromisesAwait.js b/01-node-tutorial/answers/writeWithpromisesAwait.js new file mode 100644 index 0000000000..5ad0c9610d --- /dev/null +++ b/01-node-tutorial/answers/writeWithpromisesAwait.js @@ -0,0 +1,28 @@ +const { writeFile, readFile } = require("fs").promises; + +async function writer() { + try { + await writeFile('./temporary/temp.txt', 'This is line 1\n'); + await writeFile('./temporary/temp.txt', 'This is line 2\n', { flag: 'a' }); + await writeFile('./temporary/temp.txt', 'This is line 3\n', { flag: 'a' }); + console.log('File written successfully'); + } catch (error) { + console.error('Error writing file:', error); + } +} + +async function reader() { + try { + const content = await readFile('./temporary/temp.txt', 'utf8'); + console.log(content); + } catch (error) { + console.error('Error reading file:', error); + } +} + +async function readWrite() { + await writer(); + await reader(); +} + +readWrite(); \ No newline at end of file From 01f47deb5542e980dff1831283ea79ff71728d63 Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 9 Dec 2025 22:33:39 -0800 Subject: [PATCH 3/7] week 3 --- 02-express-tutorial/app.js | 64 +++++++++++++++++++++++++++ 02-express-tutorial/public/index.html | 40 +++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 02-express-tutorial/public/index.html diff --git a/02-express-tutorial/app.js b/02-express-tutorial/app.js index ce296a6ee3..2ed8c6a55f 100644 --- a/02-express-tutorial/app.js +++ b/02-express-tutorial/app.js @@ -1 +1,65 @@ console.log('Express Tutorial') +const express = require('express'); +const { products } = require("./data"); +const app = express(); + +//Middleware +app.use(express.static('./public')); + +//API return JSON +app.get('/api/v1/test', (req, res) => { + res.json({ message: "It worked!" }); +}); + +app.get('/api/v1/products/:productID', (req, res) => { + const idToFind = parseInt(req.params.productID); + const product = products.find((p) => p.id === idToFind); + + if (!product) { return res.status(404).json({ message: "That product was not found." });} + + res.json(product); +}); + +app.get('/api/v1/query', (req, res) => { + const { search, limit, maxPrice } = req.query; + let result = [...products]; + + //filter by search when the name starts with "" + if (search) { + result = result.filter((input) => + input.name.toLowerCase().startsWith(search.toLowerCase()) + ); + } + + //filter by the max price + if (maxPrice) { + const maxPriceNum = parseFloat(maxPrice); + if (!isNaN(maxPriceNum)) { + result = result.filter((input) => input.price <= maxPriceNum); + } + } + + //limit results + if (limit) { + const limitNum = parseInt(limit); + if (!isNaN(limitNum) && limitNum > 0) { + result = result.slice(0, limitNum); + } + } + + res.json(result); +}); + +app.get('/api/v1/products', (req, res) => { + res.json(products); +}); + +//Handle Errors +app.all('*', (req, res) => { + res.status(404).send('Page not found'); +}); + +const PORT = 3000; +app.listen(PORT, () => { + console.log(`Server on port ${PORT}...`); +}); \ No newline at end of file diff --git a/02-express-tutorial/public/index.html b/02-express-tutorial/public/index.html new file mode 100644 index 0000000000..45f0b73d41 --- /dev/null +++ b/02-express-tutorial/public/index.html @@ -0,0 +1,40 @@ + + + + + + Products API + + +

Hello World! :P

+ +
+ + + + \ No newline at end of file From 29e0c39f6bad22dfcf319a5ea75835cd51c3ead6 Mon Sep 17 00:00:00 2001 From: Carl Date: Mon, 22 Dec 2025 18:55:17 -0800 Subject: [PATCH 4/7] week 5 --- 02-express-tutorial/app.js | 21 +++++++++++++++++++-- 02-express-tutorial/controllers/people.js | 22 ++++++++++++++++++++++ 02-express-tutorial/routes/people.js | 9 +++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 02-express-tutorial/controllers/people.js create mode 100644 02-express-tutorial/routes/people.js diff --git a/02-express-tutorial/app.js b/02-express-tutorial/app.js index 2ed8c6a55f..400bc3e618 100644 --- a/02-express-tutorial/app.js +++ b/02-express-tutorial/app.js @@ -1,12 +1,25 @@ console.log('Express Tutorial') const express = require('express'); const { products } = require("./data"); +const peopleRouter = require("./routes/people"); const app = express(); //Middleware + +const logger = (req, res, next) => { + const method = req.method + const url = req.url + const time = new Date().getFullYear() + console.log(method, url, time) + next() +} + +app.use(logger); app.use(express.static('./public')); +app.use(express.urlencoded({ extended: false })); +app.use(express.json()); -//API return JSON +//ROUTES app.get('/api/v1/test', (req, res) => { res.json({ message: "It worked!" }); }); @@ -54,12 +67,16 @@ app.get('/api/v1/products', (req, res) => { res.json(products); }); +app.use("/api/v1/people", peopleRouter); + + //Handle Errors app.all('*', (req, res) => { res.status(404).send('Page not found'); }); + const PORT = 3000; app.listen(PORT, () => { console.log(`Server on port ${PORT}...`); -}); \ No newline at end of file +}); diff --git a/02-express-tutorial/controllers/people.js b/02-express-tutorial/controllers/people.js new file mode 100644 index 0000000000..c3696ef1ef --- /dev/null +++ b/02-express-tutorial/controllers/people.js @@ -0,0 +1,22 @@ +const { people } = require("../data"); + +const getPeople = (req, res) => { + return res.status(200).json(people); +}; + +const addPerson = (req, res) => { + const { name } = req.body; + + if (!name) { + return res + .status(400) + .json({ success: false, message: "Please provide a name" }); +} + + const newPerson = { id: people.length + 1, name }; + people.push(newPerson); + + return res.status(201).json({ success: true, data: newPerson }); +}; + +module.exports = { getPeople, addPerson }; diff --git a/02-express-tutorial/routes/people.js b/02-express-tutorial/routes/people.js new file mode 100644 index 0000000000..ad58b33011 --- /dev/null +++ b/02-express-tutorial/routes/people.js @@ -0,0 +1,9 @@ +const express = require("express"); +const router = express.Router(); + +const { addPerson, getPeople } = require("../controllers/people"); + +router.get("/", getPeople); +router.post("/", addPerson); + +module.exports = router; From 7acbf5da8bb2ed2ac51f560a3cb771f253afaed9 Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 23 Dec 2025 09:14:17 -0800 Subject: [PATCH 5/7] week5 --- 03-task-manager/starter/app.js | 38 +++++++++++++++++++- 03-task-manager/starter/controllers/tasks.js | 30 ++++++++++++++++ 03-task-manager/starter/db/connect.js | 13 +++++++ 03-task-manager/starter/models/tasks.js | 7 ++++ 03-task-manager/starter/routes/tasks.js | 10 ++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 03-task-manager/starter/controllers/tasks.js create mode 100644 03-task-manager/starter/db/connect.js create mode 100644 03-task-manager/starter/models/tasks.js create mode 100644 03-task-manager/starter/routes/tasks.js diff --git a/03-task-manager/starter/app.js b/03-task-manager/starter/app.js index ead4ded2ef..5763eae03e 100644 --- a/03-task-manager/starter/app.js +++ b/03-task-manager/starter/app.js @@ -1 +1,37 @@ -console.log('Task Manager App') +require("dotenv").config(); + +const express = require("express"); +const app = express(); +const tasks = require("./routes/tasks"); +const connectDB = require("./db/connect"); + +// middleware +app.use(express.json()); + +// routes +app.get("/", (req, res) => { + res.send("Home"); +}); + +app.get("/hello", (req, res) => { + res.send("Task Manager App"); +}); + +app.use("/api/v1/tasks", tasks); + +const port = 3000; + +const start = async () => { + try { + await connectDB(process.env.MONGO_URI) + app.listen(port, () => + console.log(`Server is listening on port ${port}...`) + ); + } catch (error) { + console.log(error) + } +} + +start() + + diff --git a/03-task-manager/starter/controllers/tasks.js b/03-task-manager/starter/controllers/tasks.js new file mode 100644 index 0000000000..032cc770d7 --- /dev/null +++ b/03-task-manager/starter/controllers/tasks.js @@ -0,0 +1,30 @@ +const Task = require('../models/tasks') + +const getAllTask = (req, res) => { + res.send('get all tasks') +} + +const createTask = async (req, res) => { + const task = await Task.create(req.body) + res.status(201).json({task}) +} + +const getTask = (req, res) => { + res.json( {id: req.params.id} ) +} + +const updateTask = (req, res) => { + res.send('update task') +} + +const deleteTask = (req, res) => { + res.send('delete task') +} + +module.exports = { + getAllTask, + createTask, + getTask, + updateTask, + deleteTask, +} \ No newline at end of file diff --git a/03-task-manager/starter/db/connect.js b/03-task-manager/starter/db/connect.js new file mode 100644 index 0000000000..2eb44dab67 --- /dev/null +++ b/03-task-manager/starter/db/connect.js @@ -0,0 +1,13 @@ +const mongoose = require("mongoose"); + +const connectDB = (url) => { + return mongoose + .connect(url, { + useNewUrlParser: true, + useCreateIndex: true, + useFindAndModify: false, + useUnifiedTopology: true, + }) +} + +module.exports = connectDB diff --git a/03-task-manager/starter/models/tasks.js b/03-task-manager/starter/models/tasks.js new file mode 100644 index 0000000000..af1472b897 --- /dev/null +++ b/03-task-manager/starter/models/tasks.js @@ -0,0 +1,7 @@ +const mongoose = require('mongoose'); + +const TaskSchema = new mongoose.Schema({ + name:String,completed:Boolean +}) + +module.exports = mongoose.model('Task', TaskSchema) \ No newline at end of file diff --git a/03-task-manager/starter/routes/tasks.js b/03-task-manager/starter/routes/tasks.js new file mode 100644 index 0000000000..3368913c02 --- /dev/null +++ b/03-task-manager/starter/routes/tasks.js @@ -0,0 +1,10 @@ +const express = require('express'); +const router = express.Router(); +const {getAllTask,createTask,getTask,updateTask,deleteTask} = require('../controllers/tasks') + +router.route('/').get(getAllTask).post(createTask) +router.route('/:id').get(getTask).patch(updateTask).delete(deleteTask) + + + +module.exports = router \ No newline at end of file From 9c009517058b57afbd58e5ef7e49208b3358a3ae Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 6 Jan 2026 21:59:26 -0800 Subject: [PATCH 6/7] week6 --- 03-task-manager/starter/QuizAnswers2.txt | 10 ++++ 03-task-manager/starter/app.js | 14 ++--- 03-task-manager/starter/controllers/tasks.js | 60 +++++++++++++------ .../starter/errors/custom-error.js | 12 ++++ 03-task-manager/starter/middleware/async.js | 11 ++++ .../starter/middleware/error-handler.js | 9 +++ .../starter/middleware/not-found.js | 3 + 03-task-manager/starter/models/tasks.js | 15 ++++- 03-task-manager/starter/routes/tasks.js | 21 ++++--- 9 files changed, 118 insertions(+), 37 deletions(-) create mode 100644 03-task-manager/starter/QuizAnswers2.txt create mode 100644 03-task-manager/starter/errors/custom-error.js create mode 100644 03-task-manager/starter/middleware/async.js create mode 100644 03-task-manager/starter/middleware/error-handler.js create mode 100644 03-task-manager/starter/middleware/not-found.js diff --git a/03-task-manager/starter/QuizAnswers2.txt b/03-task-manager/starter/QuizAnswers2.txt new file mode 100644 index 0000000000..995ec3b0ca --- /dev/null +++ b/03-task-manager/starter/QuizAnswers2.txt @@ -0,0 +1,10 @@ +1) We Created a asyncWrapper middleware function so we can handle errors in async route automatically. Doing this we cut down on using try and catch block. It also catches any errors that occur in the async operations + +const getTask = asyncWrapper(async (req, res, next) => { + const { id: taskID } = req.params; + const task = await Task.findOne({ _id: taskID }); + if (!task) { + return next(createCustomError(`No task with id : ${taskID}`, 404)) + } + res.status(200).json({ task }); +}); \ No newline at end of file diff --git a/03-task-manager/starter/app.js b/03-task-manager/starter/app.js index 5763eae03e..7abf9d1b6b 100644 --- a/03-task-manager/starter/app.js +++ b/03-task-manager/starter/app.js @@ -1,24 +1,20 @@ require("dotenv").config(); - +const notFound = require('./middleware/not-found') const express = require("express"); const app = express(); const tasks = require("./routes/tasks"); const connectDB = require("./db/connect"); // middleware +app.use(express.static('./public')) app.use(express.json()); -// routes -app.get("/", (req, res) => { - res.send("Home"); -}); - -app.get("/hello", (req, res) => { - res.send("Task Manager App"); -}); +// routes app.use("/api/v1/tasks", tasks); +app.use(notFound) + const port = 3000; const start = async () => { diff --git a/03-task-manager/starter/controllers/tasks.js b/03-task-manager/starter/controllers/tasks.js index 032cc770d7..d49231ca12 100644 --- a/03-task-manager/starter/controllers/tasks.js +++ b/03-task-manager/starter/controllers/tasks.js @@ -1,30 +1,56 @@ const Task = require('../models/tasks') +const asyncWrapper = require('../middleware/async') +const { createCustomError } = require('../errors/custom-error') -const getAllTask = (req, res) => { - res.send('get all tasks') -} -const createTask = async (req, res) => { +const getAllTasks = asyncWrapper(async (req, res) => { + const tasks = await Task.find({}) + res.status(200).json({ tasks }) +}) + +const createTask = asyncWrapper(async (req, res) => { const task = await Task.create(req.body) - res.status(201).json({task}) -} + res.status(201).json({ task }) +}) -const getTask = (req, res) => { - res.json( {id: req.params.id} ) -} +const getTask = asyncWrapper(async (req, res, next) => { + const { id: taskID } = req.params + const task = await Task.findOne({ _id: taskID }) + if (!task) { + return next(createCustomError(`No task with id : ${taskID}`, 404)) + } -const updateTask = (req, res) => { - res.send('update task') -} + res.status(200).json({ task }) +}) -const deleteTask = (req, res) => { - res.send('delete task') -} +const deleteTask = asyncWrapper(async (req, res, next) => { + const { id: taskID } = req.params + const task = await Task.findOneAndDelete({ _id: taskID }) + if (!task) { + return next(createCustomError(`No task with id : ${taskID}`, 404)) + } + res.status(200).json({ task }) +}) + +const updateTask = asyncWrapper(async (req, res, next) => { + const { id: taskID } = req.params + + const task = await Task.findOneAndUpdate({ _id: taskID }, req.body, { + new: true, + runValidators: true, + }) + + if (!task) { + return next(createCustomError(`No task with id : ${taskID}`, 404)) + } + + res.status(200).json({ task }) +}) module.exports = { - getAllTask, + getAllTasks, createTask, getTask, updateTask, deleteTask, -} \ No newline at end of file +} diff --git a/03-task-manager/starter/errors/custom-error.js b/03-task-manager/starter/errors/custom-error.js new file mode 100644 index 0000000000..f79926a680 --- /dev/null +++ b/03-task-manager/starter/errors/custom-error.js @@ -0,0 +1,12 @@ +class CustomAPIError extends Error { + constructor(message, statusCode) { + super(message) + this.statusCode = statusCode + } +} + +const createCustomError = (msg, statusCode) => { + return new CustomAPIError(msg, statusCode) +} + +module.exports = { createCustomError, CustomAPIError } diff --git a/03-task-manager/starter/middleware/async.js b/03-task-manager/starter/middleware/async.js new file mode 100644 index 0000000000..bd5afa6f98 --- /dev/null +++ b/03-task-manager/starter/middleware/async.js @@ -0,0 +1,11 @@ +const asyncWrapper = (fn) => { +return async (req, res, next) => { + try { + await fn(req, res, next) + } catch (error) { + next(error) + } +} +} + +module.exports = asyncWrapper diff --git a/03-task-manager/starter/middleware/error-handler.js b/03-task-manager/starter/middleware/error-handler.js new file mode 100644 index 0000000000..0003e5e68e --- /dev/null +++ b/03-task-manager/starter/middleware/error-handler.js @@ -0,0 +1,9 @@ +const { CustomAPIError } = require('../errors/custom-error') +const errorHandlerMiddleware = (err, req, res, next) => { + if (err instanceof CustomAPIError) { + return res.status(err.statusCode).json({ msg: err.message }) + } + return res.status(500).json({ msg: 'Something went wrong, please try again' }) +} + +module.exports = errorHandlerMiddleware diff --git a/03-task-manager/starter/middleware/not-found.js b/03-task-manager/starter/middleware/not-found.js new file mode 100644 index 0000000000..dbf8aadc60 --- /dev/null +++ b/03-task-manager/starter/middleware/not-found.js @@ -0,0 +1,3 @@ +const notFound = (req,res) => res.status(404).send('Route does not exist') + +module.exports = notFound \ No newline at end of file diff --git a/03-task-manager/starter/models/tasks.js b/03-task-manager/starter/models/tasks.js index af1472b897..588f5c216b 100644 --- a/03-task-manager/starter/models/tasks.js +++ b/03-task-manager/starter/models/tasks.js @@ -1,7 +1,16 @@ -const mongoose = require('mongoose'); +const mongoose = require('mongoose') const TaskSchema = new mongoose.Schema({ - name:String,completed:Boolean + name: { + type: String, + required: [true, 'Must provide name'], + trim: true, + maxlength: [20, 'name can not be more than 20 characters'], + }, + completed: { + type: Boolean, + default: false, + }, }) -module.exports = mongoose.model('Task', TaskSchema) \ No newline at end of file +module.exports = mongoose.model('Task', TaskSchema) diff --git a/03-task-manager/starter/routes/tasks.js b/03-task-manager/starter/routes/tasks.js index 3368913c02..cd88830522 100644 --- a/03-task-manager/starter/routes/tasks.js +++ b/03-task-manager/starter/routes/tasks.js @@ -1,10 +1,15 @@ -const express = require('express'); -const router = express.Router(); -const {getAllTask,createTask,getTask,updateTask,deleteTask} = require('../controllers/tasks') - -router.route('/').get(getAllTask).post(createTask) +const express = require('express') +const router = express.Router() + +const { + getAllTasks, + createTask, + getTask, + updateTask, + deleteTask, +} = require('../controllers/tasks') + +router.route('/').get(getAllTasks).post(createTask) router.route('/:id').get(getTask).patch(updateTask).delete(deleteTask) - - -module.exports = router \ No newline at end of file +module.exports = router From 3e8c088f7ef8892686584003ff31157fa5534550 Mon Sep 17 00:00:00 2001 From: Carl Date: Sat, 17 Jan 2026 17:22:59 -0800 Subject: [PATCH 7/7] week7 --- 03-task-manager/starter/db/connect.js | 14 ++-- 04-store-api/starter/app.js | 42 ++++++++++- 04-store-api/starter/controllers/products.js | 73 ++++++++++++++++++++ 04-store-api/starter/db/connect.js | 13 ++-- 04-store-api/starter/models/product.js | 33 +++++++++ 04-store-api/starter/populate.js | 22 ++++++ 04-store-api/starter/routes/products.js | 9 +++ 7 files changed, 187 insertions(+), 19 deletions(-) diff --git a/03-task-manager/starter/db/connect.js b/03-task-manager/starter/db/connect.js index 2eb44dab67..1c234954d7 100644 --- a/03-task-manager/starter/db/connect.js +++ b/03-task-manager/starter/db/connect.js @@ -1,13 +1,9 @@ const mongoose = require("mongoose"); +console.log("CONNECT FILE LOADED:", __filename) + const connectDB = (url) => { - return mongoose - .connect(url, { - useNewUrlParser: true, - useCreateIndex: true, - useFindAndModify: false, - useUnifiedTopology: true, - }) -} + return mongoose.connect(url); +}; -module.exports = connectDB +module.exports = connectDB; diff --git a/04-store-api/starter/app.js b/04-store-api/starter/app.js index a8f48255db..dac336e295 100644 --- a/04-store-api/starter/app.js +++ b/04-store-api/starter/app.js @@ -1 +1,41 @@ -console.log('04 Store API') +require('dotenv').config() +require('express-async-errors') +// async error + +const express = require('express'); +const app = express() + +const connectDB = require('./db/connect') + +const productRouter = require('./routes/products') + +const notFoundMiddleware = require('./middleware/not-found') +const errorMiddleware = require('./middleware/not-found') + +//middleware +app.use(express.json()) + +//routes +app.get('/', (req, res) => { + res.send('

Store API

products route'); +}) + +app.use('/api/v1/products',productRouter) + +//products route +app.use(notFoundMiddleware) +app.use(errorMiddleware) + +const port = process.env.port || 3000 + +const start = async () => { + try { + //connectDB + await connectDB(process.env.MONGO_URI) + app.listen(port, console.log(`Server is listening port ${port}...`)) + } catch (error) { + console.log(error) + } +} + +start() \ No newline at end of file diff --git a/04-store-api/starter/controllers/products.js b/04-store-api/starter/controllers/products.js index e69de29bb2..259afbd8a0 100644 --- a/04-store-api/starter/controllers/products.js +++ b/04-store-api/starter/controllers/products.js @@ -0,0 +1,73 @@ +const Product = require('../models/product'); + +const getAllProductsStatic = async (req, res) => { +const products = await Product.find({ price: { $gt: 30 } }) + .sort('price') + .select('name price'); + +res.status(200).json({ products, nbHits: products.length }); +}; +const getAllProducts = async (req, res) => { +const { featured, company, name, sort, fields, numericFilters } = req.query; +const queryObject = {}; + +if (featured) { + queryObject.featured = featured === 'true' ? true : false; +} +if (company) { + queryObject.company = company; +} +if (name) { + queryObject.name = { $regex: name, $options: 'i' }; +} +if (numericFilters) { + const operatorMap = { + '>': '$gt', + '>=': '$gte', + '=': '$eq', + '<': '$lt', + '<=': '$lte', + }; + const regEx = /\b(<|>|>=|=|<|<=)\b/g; + let filters = numericFilters.replace( + regEx, + (match) => `-${operatorMap[match]}-` + ); + const options = ['price', 'rating']; + filters = filters.split(',').forEach((item) => { + const [field, operator, value] = item.split('-'); + if (options.includes(field)) { + queryObject[field] = { [operator]: Number(value) }; + } + }); +} + +let result = Product.find(queryObject); +// sort +if (sort) { + const sortList = sort.split(',').join(' '); + result = result.sort(sortList); +} else { + result = result.sort('createdAt'); +} + +if (fields) { + const fieldsList = fields.split(',').join(' '); + result = result.select(fieldsList); +} +const page = Number(req.query.page) || 1; +const limit = Number(req.query.limit) || 10; +const skip = (page - 1) * limit; + +result = result.skip(skip).limit(limit); +// 23 +// 4 7 7 7 2 + +const products = await result; +res.status(200).json({ products, nbHits: products.length }); +}; + +module.exports = { +getAllProducts, +getAllProductsStatic, +}; diff --git a/04-store-api/starter/db/connect.js b/04-store-api/starter/db/connect.js index 3a3beeb7f5..935e3d5a74 100644 --- a/04-store-api/starter/db/connect.js +++ b/04-store-api/starter/db/connect.js @@ -1,12 +1,7 @@ -const mongoose = require('mongoose') +const mongoose = require("mongoose"); const connectDB = (url) => { - return mongoose.connect(url, { - useNewUrlParser: true, - useCreateIndex: true, - useFindAndModify: false, - useUnifiedTopology: true, - }) -} + return mongoose.connect(url); +}; -module.exports = connectDB +module.exports = connectDB; diff --git a/04-store-api/starter/models/product.js b/04-store-api/starter/models/product.js index e69de29bb2..903b378e0d 100644 --- a/04-store-api/starter/models/product.js +++ b/04-store-api/starter/models/product.js @@ -0,0 +1,33 @@ +const mongoose = require('mongoose') + +const productSchema = new mongoose.Schema({ + name:{ + type:String, + required:[true,'Product name must be provided'] + }, + price:{ + type:String, + required:[true,'Product price must be provided'] + }, + featured: { + type: Boolean, + default:false + }, + rating: { + type: Number, + default: 4.5 + }, + createAt:{ + type:Date, + default:Date.now(), + }, + company:{ + type:String, + enum:{ + values: ['ikea', 'liddy', 'caressa', 'marcos'], + message: '{VALUE is not supported}' + } + }, +}) + +module.exports = mongoose.model('Product', productSchema) diff --git a/04-store-api/starter/populate.js b/04-store-api/starter/populate.js index e69de29bb2..5015a360ff 100644 --- a/04-store-api/starter/populate.js +++ b/04-store-api/starter/populate.js @@ -0,0 +1,22 @@ +require('dotenv').config() + +const connectDB = require('./db/connect') +const Product = require('./models/product') + +const jsonProducts = require('./products.json') + +const start = async () => { + try { + console.log(Product.modelName) + await connectDB(process.env.MONGO_URI) + await Product.deleteMany() + await Product.create(jsonProducts) + console.log('Success!!!!') + process.exit(0) + } catch (error) { + console.log(error) + process.exit(1) + } +} + +start() diff --git a/04-store-api/starter/routes/products.js b/04-store-api/starter/routes/products.js index e69de29bb2..6013b2a8e8 100644 --- a/04-store-api/starter/routes/products.js +++ b/04-store-api/starter/routes/products.js @@ -0,0 +1,9 @@ +const express = require('express') +const router = express.Router() + +const {getAllProducts, getAllProductStatic} = require('../controllers/products') + +router.route('/').get(getAllProducts) +router.route('/static').get(getAllProductStatic) + +module.exports = router \ No newline at end of file