Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions models/LikedThought.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const mongoose = require('mongoose');

const LikedThoughtSchema = new mongoose.Schema({
thoughtId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Thought',
required: true, // Reference to the original Thought
},
message: {
type: String,
required: true, // Save the thought message for quick access
},
likedAt: {
type: Date,
default: Date.now, // Timestamp for when the thought was liked
},
});

module.exports = mongoose.model('LikedThought', LikedThoughtSchema);
20 changes: 20 additions & 0 deletions models/Thought.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const mongoose = require('mongoose');

const ThoughtSchema = new mongoose.Schema({
message: {
type: String,
required: [true, "Message is required"],
minlength: [5, "Message must be at least 5 characters"],
maxlength: [140, "Message must be at most 140 characters"],
},
hearts: {
type: Number,
default: 0,
},
createdAt: {
type: Date,
default: Date.now, // Auto-generated timestamp
},
});

module.exports = mongoose.model('Thought', ThoughtSchema);
15 changes: 11 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"body-parser": "^1.20.3",
"cors": "^2.8.5",
"express": "^4.17.3",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
"dotenv": "^16.4.7",
"express": "^4.21.2",
"mongodb": "^6.13.0",
"mongoose": "^8.9.6"
},
"main": "server.js",
"keywords": [],
"devDependencies": {
"nodemon": "^3.1.9"
}
}
}
63 changes: 63 additions & 0 deletions routes/thoughtsRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const express = require('express');
const Thought = require('../models/Thought');
const LikedThought = require('../models/LikedThought'); // Import LikedThought model
const router = express.Router();

// 📌 GET /thoughts → Fetch the latest 20 thoughts, sorted by `createdAt` (DESC)
router.get('/', async (req, res) => {
try {
const thoughts = await Thought.find().sort({ createdAt: -1 }).limit(20);
res.status(200).json(thoughts); // Return thoughts
} catch (error) {
console.error('Error fetching thoughts:', error); // Log error for debugging
res.status(500).json({ error: 'Error fetching thoughts' }); // Send 500 error response
}
});

// 📌 POST /thoughts → Create a new thought
router.post('/', async (req, res) => {
const { message } = req.body;

// Validate message length
if (!message || message.length < 5 || message.length > 140) {
return res.status(400).json({ error: 'Message must be between 5 and 140 characters' });
}

try {
const newThought = await Thought.create({ message }); // Save the new thought
res.status(201).json(newThought); // Return the created thought with 201 status
} catch (error) {
console.error('Error creating thought:', error); // Log error for debugging
res.status(500).json({ error: 'Could not save thought' }); // Send 500 error response
}
});

// 📌 POST /thoughts/:id/like → Increment hearts and store liked thought in LikedThoughts
router.post('/:id/like', async (req, res) => {
try {
// Find and update the original thought
const updatedThought = await Thought.findByIdAndUpdate(
req.params.id,
{ $inc: { hearts: 1 } }, // Increment `hearts` by 1
{ new: true } // Return the updated thought
);

if (!updatedThought) {
return res.status(404).json({ error: 'Thought not found' }); // Handle non-existent thought
}

// Save the liked thought in the LikedThoughts collection
await LikedThought.create({
thoughtId: updatedThought._id, // Reference the original thought
message: updatedThought.message, // Copy the message for easier access
likedAt: new Date(), // Timestamp when the thought was liked
});

res.status(200).json(updatedThought); // Return the updated thought
} catch (error) {
console.error('Error liking thought:', error); // Log error for debugging
res.status(500).json({ error: 'Error updating hearts' }); // Send 500 error response
}
});

module.exports = router;
72 changes: 51 additions & 21 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,57 @@
import cors from "cors";
import express from "express";
import mongoose from "mongoose";

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
// when starting the server. Example command to overwrite PORT env variable value:
// PORT=9000 npm start
const port = process.env.PORT || 8080;
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const thoughtRoutes = require('./routes/thoughtsRoutes');

const app = express();

// Add middlewares to enable cors and json body parsing
app.use(cors());
app.use(express.json());
// 📌 Middleware
app.use(cors()); // Enable CORS for cross-origin requests
app.use(express.json()); // Parse JSON request bodies

// 📌 Connect to MongoDB
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("✅ Connected to MongoDB"))
.catch((err) => {
console.error("❌ MongoDB connection error:", err);
process.exit(1); // Exit the server if the database connection fails
});

// 📌 Default API Route
app.get('/', (req, res) => {
res.json([
{ "path": "/", "methods": ["GET"], "middleware": ["anonymous"] },
{ "path": "/thoughts", "methods": ["GET", "POST"], "middleware": ["anonymous"] },
{ "path": "/thoughts/:id/like", "methods": ["POST"], "middleware": ["anonymous"] }
]);
});

// 📌 Use Thought Routes
app.use('/thoughts', thoughtRoutes);

// 📌 Error Handling Middleware
app.use((err, req, res, next) => {
console.error(err.stack); // Log error stack for debugging
res.status(500).json({ error: 'An internal server error occurred.' });
});

// 📌 Start the Server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT}`);
});

// Start defining your routes here
app.get("/", (req, res) => {
res.send("Hello Technigo!");
// Handle uncaught exceptions and unhandled rejections
process.on('uncaughtException', (err) => {
console.error("❌ Uncaught Exception:", err);
process.exit(1);
});

// Start the server
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
process.on('unhandledRejection', (reason, promise) => {
console.error("❌ Unhandled Rejection at:", promise, "reason:", reason);
process.exit(1);
});