From ebc60f86707a136ffcd517849f0b7d457057030d Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Thu, 19 Dec 2024 22:59:19 +0100 Subject: [PATCH 1/8] Installed dependencies and connected to MongoDB Atlas --- package.json | 4 +++- server.js | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1c371b45..ed001e51 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "@babel/node": "^7.16.8", "@babel/preset-env": "^7.16.11", "cors": "^2.8.5", + "dotenv": "^16.4.7", "express": "^4.17.3", + "mongodb": "^6.12.0", "mongoose": "^8.0.0", "nodemon": "^3.0.1" } -} \ No newline at end of file +} diff --git a/server.js b/server.js index dfe86fb8..6949e54d 100644 --- a/server.js +++ b/server.js @@ -1,9 +1,20 @@ import cors from "cors"; import express from "express"; import mongoose from "mongoose"; +import dotenv from "dotenv"; + +dotenv.config(); + +// const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; +const mongoUrl = process.env.MONGO_URL; +mongoose.connect(mongoUrl) + .then(() => { + console.log('Connected to MongoDB Atlas'); + }) + .catch((error) => { + console.error('Error connecting to MongoDB Atlas:', error); + }); -const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; -mongoose.connect(mongoUrl); mongoose.Promise = Promise; // Defines the port the app will run on. Defaults to 8080, but can be overridden From 726de8dbf5c97cfd43d52222c94c7b45eec1c340 Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Thu, 19 Dec 2024 23:20:43 +0100 Subject: [PATCH 2/8] Added mongoose schema and model --- server.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 6949e54d..7bb4917f 100644 --- a/server.js +++ b/server.js @@ -3,10 +3,12 @@ import express from "express"; import mongoose from "mongoose"; import dotenv from "dotenv"; +// Load environment variables from env. file dotenv.config(); // const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; -const mongoUrl = process.env.MONGO_URL; +const mongoUrl = process.env.MONGO_URI; // Add mongodb localhost here + mongoose.connect(mongoUrl) .then(() => { console.log('Connected to MongoDB Atlas'); @@ -17,6 +19,26 @@ mongoose.connect(mongoUrl) mongoose.Promise = Promise; +// Mongoose schema and model +const thoughtSchema = new mongoose.Schema({ + message: { + type: String, + requires: true, + minlength: 5, + maxlength: 140 + }, + hearts: { + type: Number, + default: 0 + }, + createdAt: { + type: Date, + default: Date.now + } +}); + +const Thought = mongoose.model("Thought", thoughtSchema); + // Defines the port the app will run on. Defaults to 8080, but can be overridden // when starting the server. Example command to overwrite PORT env variable value: // PORT=9000 npm start From a4790c9b8bc484ee2ad7634a4a66d366b799e56c Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Thu, 19 Dec 2024 23:37:57 +0100 Subject: [PATCH 3/8] Created thoughts route and listEndpoints with express --- package.json | 1 + server.js | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ed001e51..2b5c33db 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.7", "express": "^4.17.3", + "list-endpoints-express": "^1.0.1", "mongodb": "^6.12.0", "mongoose": "^8.0.0", "nodemon": "^3.0.1" diff --git a/server.js b/server.js index 7bb4917f..060a4891 100644 --- a/server.js +++ b/server.js @@ -2,6 +2,7 @@ import cors from "cors"; import express from "express"; import mongoose from "mongoose"; import dotenv from "dotenv"; +import listEndpoints from "list-endpoints-express"; // Load environment variables from env. file dotenv.config(); @@ -51,7 +52,20 @@ app.use(express.json()); // Start defining your routes here app.get("/", (req, res) => { - res.send("Hello Technigo!"); + const endpoints = listEndpoints(app); // Automaticlly list all endpoints + res.json({ + message: "Hello! Here are all the available endpoints:", + endpoints: endpoints + }); +}); + +app.get("/thoughts", async (req, res) => { + try { + const thoughts = await Thought.find().sort({ createdAt: -1 }).limit(20); + res.status(200).json(thoughts); + } catch (error) { + res.status(400).json({ error: error.message }); + } }); // Start the server From d23514fd84a75b2620ad09ceede8c68c4e79da00 Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Fri, 20 Dec 2024 17:10:27 +0100 Subject: [PATCH 4/8] Created new thought route and like thought route --- server.js | 80 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/server.js b/server.js index 060a4891..5c2ab878 100644 --- a/server.js +++ b/server.js @@ -7,8 +7,16 @@ import listEndpoints from "list-endpoints-express"; // Load environment variables from env. file dotenv.config(); -// const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; -const mongoUrl = process.env.MONGO_URI; // Add mongodb localhost here +// Defines the port the app will run on, defaults to 8080 +const port = process.env.PORT || 8080; +const app = express(); + +// Add middlewares to enable cors and json body parsing +app.use(cors()); +app.use(express.json()); + +// Check Mongo link is in env. file +const mongoUrl = process.env.MONGO_URI; mongoose.connect(mongoUrl) .then(() => { @@ -18,13 +26,11 @@ mongoose.connect(mongoUrl) console.error('Error connecting to MongoDB Atlas:', error); }); -mongoose.Promise = Promise; - // Mongoose schema and model const thoughtSchema = new mongoose.Schema({ message: { type: String, - requires: true, + required: true, minlength: 5, maxlength: 140 }, @@ -40,17 +46,8 @@ const thoughtSchema = new mongoose.Schema({ const Thought = mongoose.model("Thought", thoughtSchema); -// Defines the port the app will run on. Defaults to 8080, but can be overridden -// when starting the server. Example command to overwrite PORT env variable value: -// PORT=9000 npm start -const port = process.env.PORT || 8080; -const app = express(); - -// Add middlewares to enable cors and json body parsing -app.use(cors()); -app.use(express.json()); - // Start defining your routes here +// Home route showing all the endpoints app.get("/", (req, res) => { const endpoints = listEndpoints(app); // Automaticlly list all endpoints res.json({ @@ -59,15 +56,62 @@ app.get("/", (req, res) => { }); }); +// Fetch all thoughts and show 20 latest thoughts app.get("/thoughts", async (req, res) => { try { - const thoughts = await Thought.find().sort({ createdAt: -1 }).limit(20); - res.status(200).json(thoughts); + const thoughts = await Thought.find() + .sort({ createdAt: -1 }) // Sort in descending order + .limit(20); // Limit to 20 results + + res.status(200).json(thoughts); // Return the thoughts } catch (error) { - res.status(400).json({ error: error.message }); + res.status(400).json({ error: error.message }); // Handle error } }); +// Create a thought and save thought including id +app.post("/thoughts", async (req, res) => { + try { + const { message } = req.body + + if (!message || typeof message !== "string") { + return res.status(400).json({ error: "Invalid input. 'message' is required and must be a string" }); + } + + const thought = new Thought ({ message }); + const savedThought = await thought.save(); + + res.status(201).json(savedThought); + } catch (error) { + console.error("Error saving thought:", error); + res.status(500).json({ error: "An error occurred while saving thought"}); + } +}); + + +// Like a thought +app.post("/thoughts/:thoughtId/like", async (req, res) => { + try { + const { thoughtId } = req.params; + + const thought = await Thought.findByIdAndUpdate( + thoughtId, + { $inc: { hearts: 1} }, + { new: true } + ); + + if (!thought) { + return res.status(404).json({ error: "Thought not found." }); + } + + // Respond with the updated thought + res.status(200).json(thought); + } catch (error) { + console.error("Error updating hearts:", error.message); + res.status(500).json({ error: "An error occurred while liking the thought." }) + } +}); + // Start the server app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); From ddc692fecc6b2621f8f5fa701f374ff746a16423 Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Fri, 20 Dec 2024 19:14:55 +0100 Subject: [PATCH 5/8] Clean up --- server.js | 75 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/server.js b/server.js index 5c2ab878..0ea2da5e 100644 --- a/server.js +++ b/server.js @@ -7,25 +7,6 @@ import listEndpoints from "list-endpoints-express"; // Load environment variables from env. file dotenv.config(); -// Defines the port the app will run on, defaults to 8080 -const port = process.env.PORT || 8080; -const app = express(); - -// Add middlewares to enable cors and json body parsing -app.use(cors()); -app.use(express.json()); - -// Check Mongo link is in env. file -const mongoUrl = process.env.MONGO_URI; - -mongoose.connect(mongoUrl) - .then(() => { - console.log('Connected to MongoDB Atlas'); - }) - .catch((error) => { - console.error('Error connecting to MongoDB Atlas:', error); - }); - // Mongoose schema and model const thoughtSchema = new mongoose.Schema({ message: { @@ -46,36 +27,55 @@ const thoughtSchema = new mongoose.Schema({ const Thought = mongoose.model("Thought", thoughtSchema); -// Start defining your routes here -// Home route showing all the endpoints +// MongoDB connection setup +const mongoUrl = process.env.MONGO_URI; + +mongoose.connect(mongoUrl) + .then(() => { + console.log('Connected to MongoDB Atlas'); + }) + .catch((error) => { + console.error('Error connecting to MongoDB Atlas:', error); + }); + +// Defines the port the app will run on, defaults to 8080 +const port = process.env.PORT || 8080; +const app = express(); + +// Add middlewares to enable cors and json body parsing +app.use(cors()); +app.use(express.json()); + +// Route definitions +// Home route showing all endpoints app.get("/", (req, res) => { - const endpoints = listEndpoints(app); // Automaticlly list all endpoints + const endpoints = listEndpoints(app); // Automatically list all endpoints res.json({ message: "Hello! Here are all the available endpoints:", endpoints: endpoints }); }); -// Fetch all thoughts and show 20 latest thoughts +// Fetch all thoughts and show the latest 20 thoughts app.get("/thoughts", async (req, res) => { try { const thoughts = await Thought.find() - .sort({ createdAt: -1 }) // Sort in descending order - .limit(20); // Limit to 20 results + .sort({ createdAt: -1 }) // Sort in descending order + .limit(20); // Limit to 20 results - res.status(200).json(thoughts); // Return the thoughts + res.status(200).json(thoughts); // Return thoughts } catch (error) { res.status(400).json({ error: error.message }); // Handle error } }); -// Create a thought and save thought including id +// Create a new thought and save thought including id app.post("/thoughts", async (req, res) => { try { const { message } = req.body if (!message || typeof message !== "string") { - return res.status(400).json({ error: "Invalid input. 'message' is required and must be a string" }); + return res.status(400).json({ error: "Invalid input. 'message' is required and must be a string" }); // Handle error } const thought = new Thought ({ message }); @@ -84,12 +84,11 @@ app.post("/thoughts", async (req, res) => { res.status(201).json(savedThought); } catch (error) { console.error("Error saving thought:", error); - res.status(500).json({ error: "An error occurred while saving thought"}); + res.status(500).json({ error: "An error occurred while saving the thought"}); // Handle error } }); - -// Like a thought +// Like a thought and save the like app.post("/thoughts/:thoughtId/like", async (req, res) => { try { const { thoughtId } = req.params; @@ -101,15 +100,15 @@ app.post("/thoughts/:thoughtId/like", async (req, res) => { ); if (!thought) { - return res.status(404).json({ error: "Thought not found." }); + return res.status(404).json({ error: "Thought not found." }); // No thought was found with this ID } - // Respond with the updated thought - res.status(200).json(thought); - } catch (error) { - console.error("Error updating hearts:", error.message); - res.status(500).json({ error: "An error occurred while liking the thought." }) - } + // Respond with the updated thought + res.status(200).json(thought); + } catch (error) { + console.error("Error updating hearts:", error.message); + res.status(500).json({ error: "An error occurred while liking the thought." }) + } }); // Start the server From b180389eaede1cddd7824080f3047f2bde9d4a96 Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Fri, 20 Dec 2024 19:51:06 +0100 Subject: [PATCH 6/8] Fixed express-list-endpoints typo and added content to readme file --- README.md | 10 ++-------- package.json | 1 + server.js | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6a75d8e1..8aabe8bf 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,7 @@ # Project Happy Thoughts API - -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +This project is a Happy Thoughts Messaging API built with Express and MongoDB. It lets users create new thoughts, view the latest ones, and like a thought by adding hearts. I connected the project with my frontend Happy Thoughts project, enabling the API to handle requests and interact with the frontend. ## The problem - -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +This project uses Express for the backend API, MongoDB with Mongoose for data storage, and dotenv for environment variable management. CORS handles cross-origin requests, and list-endpoints-express lists available API routes. I started with connecting the project to MongoDB Atlas and then built the required endpoints step by step. I made a small mistake when importing the express-list-endpoints, which caused my endpoints to appear incorrectly. After realizing the mistake, I was able to fix it and get the home route to display the endpoints in a structured order. ## View it live - -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. diff --git a/package.json b/package.json index 2b5c33db..7d902639 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.7", "express": "^4.17.3", + "express-list-endpoints": "^7.1.1", "list-endpoints-express": "^1.0.1", "mongodb": "^6.12.0", "mongoose": "^8.0.0", diff --git a/server.js b/server.js index 0ea2da5e..0bd7dcdc 100644 --- a/server.js +++ b/server.js @@ -2,7 +2,7 @@ import cors from "cors"; import express from "express"; import mongoose from "mongoose"; import dotenv from "dotenv"; -import listEndpoints from "list-endpoints-express"; +import listEndpoints from "express-list-endpoints"; // Load environment variables from env. file dotenv.config(); @@ -51,7 +51,7 @@ app.use(express.json()); app.get("/", (req, res) => { const endpoints = listEndpoints(app); // Automatically list all endpoints res.json({ - message: "Hello! Here are all the available endpoints:", + message: "Hello and welcome to Happy Thoughts! Here are all the available endpoints:", endpoints: endpoints }); }); From a4ae965237174ad3bc28738292dc04a9cc7608c9 Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Fri, 20 Dec 2024 20:19:08 +0100 Subject: [PATCH 7/8] Added render link to readme file and edited home route message --- README.md | 1 + server.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8aabe8bf..6906b022 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,4 @@ This project is a Happy Thoughts Messaging API built with Express and MongoDB. I This project uses Express for the backend API, MongoDB with Mongoose for data storage, and dotenv for environment variable management. CORS handles cross-origin requests, and list-endpoints-express lists available API routes. I started with connecting the project to MongoDB Atlas and then built the required endpoints step by step. I made a small mistake when importing the express-list-endpoints, which caused my endpoints to appear incorrectly. After realizing the mistake, I was able to fix it and get the home route to display the endpoints in a structured order. ## View it live +https://project-happy-thoughts-api-pxns.onrender.com/ \ No newline at end of file diff --git a/server.js b/server.js index 0bd7dcdc..3994b22c 100644 --- a/server.js +++ b/server.js @@ -51,7 +51,7 @@ app.use(express.json()); app.get("/", (req, res) => { const endpoints = listEndpoints(app); // Automatically list all endpoints res.json({ - message: "Hello and welcome to Happy Thoughts! Here are all the available endpoints:", + message: "Hello and welcome to the Happy Thoughts API! Here are all the available endpoints:", endpoints: endpoints }); }); From 77c5be6d551c558114f680eea25f1e950d7c4f97 Mon Sep 17 00:00:00 2001 From: Elina Eriksson Hult Date: Sat, 21 Dec 2024 01:13:24 +0100 Subject: [PATCH 8/8] Deleted console log for debugging --- server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server.js b/server.js index 3994b22c..6e407bf5 100644 --- a/server.js +++ b/server.js @@ -81,6 +81,7 @@ app.post("/thoughts", async (req, res) => { const thought = new Thought ({ message }); const savedThought = await thought.save(); + console.log("New thought saved:", savedThought); res.status(201).json(savedThought); } catch (error) { console.error("Error saving thought:", error);