You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
5.4 KiB
JavaScript
200 lines
5.4 KiB
JavaScript
/*
|
|
s41 - Express.js - Data Persistence via Mongoose ODM
|
|
*/
|
|
|
|
const express = require('express');
|
|
|
|
const mongoose = require('mongoose');
|
|
|
|
const app = express();
|
|
const port = 3001;
|
|
|
|
// [Section] MongoDB Connection
|
|
/*
|
|
Syntax:
|
|
mongoose.connect("<MongoDB URI>", {
|
|
useNewUrlParser: true,
|
|
useUnifiedTopology: true
|
|
});
|
|
*/
|
|
|
|
// Connecting to MongoDB Atlas
|
|
mongoose.connect("mongodb+srv://jerrycabuntucan:EvDaqSDV8DIXZTQr@b320-cluster.ke6t1wi.mongodb.net/b320-todo?retryWrites=true&w=majority", {
|
|
useNewUrlParser: true,
|
|
useUnifiedTopology: true
|
|
});
|
|
|
|
// Set Notifications for connection success or failure
|
|
let db = mongoose.connection;
|
|
|
|
// If a connection error occurred, output in the console
|
|
// console.error.bind(console) allows us to print error in the browser console and in the terminal
|
|
db.on("error", console.error.bind(console, "connection error"));
|
|
|
|
// If the connection is successful, output in the console
|
|
db.once("open", () => console.log("We're connected to the cloud database!"));
|
|
|
|
|
|
// [Section] Mongoose Schema
|
|
/*
|
|
- Schemas determine the structure of the documents to be written in the database
|
|
- It will act as a blueprint to our data(documents)
|
|
*/
|
|
|
|
// The "new" keyword creates a new Schema
|
|
const taskSchema = new mongoose.Schema({
|
|
// Define the fields with the corresponding data type
|
|
// The field called "name" and its data type is "String"
|
|
name: String,
|
|
|
|
// This is the "status" field that is a "String" and the default value is "pending"
|
|
status: {
|
|
type: String,
|
|
default: "pending"
|
|
}
|
|
});
|
|
|
|
|
|
//User Schema
|
|
const userSchema = new mongoose.Schema({
|
|
username: String,
|
|
password: String
|
|
});
|
|
|
|
|
|
// [Section] Models
|
|
/*
|
|
- It uses schemas and are used to create/instantiate objects that correspond to the schema
|
|
- Models use Schemas and they act as a middleman between the server(JS code) to our database(MongoDB)
|
|
- Server > Schema (blueprint) > Database > Collection
|
|
*/
|
|
const Task = mongoose.model("Task", taskSchema);
|
|
|
|
//User Model
|
|
const User = mongoose.model("User", userSchema);
|
|
|
|
|
|
|
|
// Middlewares
|
|
app.use(express.json());
|
|
app.use(express.urlencoded({extended: true}));
|
|
|
|
|
|
// [Section] Routes
|
|
|
|
// Creating a new task
|
|
/*
|
|
Business Logic:
|
|
1. Add a functionality to check if there are duplicated tasks
|
|
- If the task already exists in the DB, we return an error
|
|
- If the task doesn't exist in the DB, we add it in the DB
|
|
2. The task data will be coming from the request's body
|
|
3. Create a new Task object with a "name" field/property
|
|
4. The "status" property does not need to be provided because our schema defaults it to "pending" upon creation of an object
|
|
*/
|
|
|
|
app.post("/tasks", (req, res) => {
|
|
|
|
// It will search the req.body.name in the db to check if it exist already in the db
|
|
Task.findOne({name: req.body.name}).then((result, err) => {
|
|
|
|
// If a docuent was found and the document's name matches the information sent via the client/postman
|
|
if(result != null && result.name == req.body.name){
|
|
|
|
// Return a message to the client/Postman
|
|
return res.send("Duplicate task found");
|
|
|
|
// If no document as found
|
|
} else {
|
|
|
|
// Create a new task and save it to the database
|
|
let newTask = new Task({
|
|
name: req.body.name
|
|
});
|
|
|
|
// The .save method is used to save the new object to the database
|
|
newTask.save().then((savedTask, saveErr) => {
|
|
// If there are errors in save, console.error the error
|
|
if(saveErr){
|
|
|
|
return console.error(saveErr);
|
|
|
|
// No error found while creating the document, return a response
|
|
} else {
|
|
// Return a status code of 201, which means created successfully
|
|
// Sends a message "New task created" on successfull creation
|
|
return res.status(201).send("New task created");
|
|
}
|
|
});
|
|
}
|
|
})
|
|
});
|
|
|
|
|
|
// Getting all the tasks
|
|
/*
|
|
Business Logic:
|
|
1. Retrieve all the documents.
|
|
2. if an error is encountered, print the error.
|
|
3. If no errors are found, send a success status back to the client/Postman and return an array of documents.
|
|
*/
|
|
app.get("/tasks", (req, res) => {
|
|
|
|
// "find" is a Mongoose method used to retrieve documents in the database, and with {}, we are going to retrieve all the documents
|
|
Task.find({}).then((result, err) => {
|
|
|
|
// If an error occurred
|
|
if(err){
|
|
|
|
// Will print any errors found in the console
|
|
return console.error(err);
|
|
|
|
// If no errors are found
|
|
} else {
|
|
|
|
// The returned response is added in an object with the "data" property.
|
|
// status "200" means that everything is "OK"
|
|
// The "json" method allows us to send a JSON format for the response
|
|
return res.status(200).json({
|
|
data: result
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
app.post("/signup", (req, res) => {
|
|
console.log(req.body);
|
|
|
|
User.findOne({username: req.body.username}).then((result,err) => {
|
|
if(result != null && result.username == req.body.username){
|
|
return res.send("Duplicate username found");
|
|
}
|
|
else {
|
|
if(req.body.username !== "" && req.body.password !== ""){
|
|
let newUser = new User({
|
|
username: req.body.username,
|
|
password: req.body.password
|
|
});
|
|
|
|
newUser.save().then((savedUser, savedErr) => {
|
|
if(savedErr){
|
|
return console.error(savedErr);
|
|
}
|
|
else{
|
|
return res.status(201).send("New User Registered");
|
|
}
|
|
})
|
|
}
|
|
else {
|
|
return res.send("BOTH username and password must be provided");
|
|
}
|
|
}
|
|
})
|
|
});
|
|
|
|
if(require.main === module){
|
|
app.listen(port, () => console.log(`Server running at port ${port}`));
|
|
}
|
|
|
|
module.exports = app; |