Skip to content

Instantly share code, notes, and snippets.

@AlexMercedCoder
Last active June 14, 2023 14:39
Show Gist options
  • Save AlexMercedCoder/b83334dc4710b8f37e6b265e0a93c2e9 to your computer and use it in GitHub Desktop.
Save AlexMercedCoder/b83334dc4710b8f37e6b265e0a93c2e9 to your computer and use it in GitHub Desktop.
Reference For ExpressJS and Mongo
/////////////////////////////////
// ./models/connection.js
/////////////////////////////////
// PURPOSE OF THIS FILE TO CONNECT TO MONGO AND EXPORT CONNECTED MONGO OBJECT
require("dotenv").config(); // Loads variables from .env into the process.env object
const mongoose = require('mongoose'); // import a fresh mongoose object
//connect to our db
mongoose.connect(
//connection string
process.env.DATABASE_URL,
//for warnings regarding the connection
{
useNewUrlParser: true,
useUnifiedTopology: true
}
)
// create logs that happen when the connection opens, closes or fails to connect
mongoose.connection
// runs callback when a connection is established
.on('open', () => console.log('Mongoose connected'))
// runs callback whena a connection is terminated
.on('close', () => console.log('Disconnected from Mongoose'))
// runs callback when a connection fails to establish, passes error message to callback
.on('error', (error) => console.log(error))
// export the connected mongoose object
module.exports = mongoose;
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////
// ./models/dog.js
/////////////////////////////////
// PURPOSE OF THIS FILE IS TOO IMPORT CONNECTED MONGO OBJECT, CREATE SCHEMA, CREATE MODEL, EXPORT MODEL
// import the connection file
const mongoose = require('./connection');
//the variable holds a schema.
//a schema defines the properties/shape of a single data type
const dogSchema = new mongoose.Schema({
name: String,
age: Number,
adopted: Boolean
});
// A Mongoose model allows us to interact with the database for that data type
// A model is made with mongoose.model(modelName, schema)
// first argument is a string representing the name of the model (should be singular)
// second argument is the schema that the model should enforce
// variables for models should be Pascal Case and singular by convention (capitalized first letter)
const Dog = mongoose.model('dog', dogSchema);
// Export the Model to be used in other files
module.exports = Dog;
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////
// ./controllers/dog.js
/////////////////////////////////
// PURPOSE IS TO DEFINE ROUTES FOR "/dog" requests, the DOG model is imported and used to interact with database as needed
// import dependencies
const express = require("express") // express library
// import the Dog model into a variable
const Dog = require('../models/dog');
// create a router
const router = express.Router()
// Function for Catching Errors
// takes a request object and returns a error handling function
const catcher = (res) => (error) => res.status(500).json({error})
// ROUTES
// INDEX - GET - LIST ALL DOGS - /dog
// ASYNC keyword allows the AWAIT keyword to be used in the function
// AWAIT pauses function till promise resolves
router.get("/", async (req, res) => {
// Get Dogs from Database using model.find({})
// the .catch handles a situation the database throws and error
const dogs = await Dog.find({}).catch(catcher(res));
// render an ejs template with all the dogs
res.render("dog/index.ejs", { dogs })
})
// NEW - GET - SHOW A FORM TO CREATE A Dog
router.get("/new", (req, res) => {
// render the new template
res.render("dog/new.ejs")
})
// DESTROY - DELETE - DELETE A Dog
router.delete("/:id", async (req, res) => {
// get the database id from the url
const id = req.params.id
// delete the dog using model.findByIdAndRemove(id)
await Dog.findByIdAndRemove(id).catch(catcher(res))
// redirect user back to index
res.redirect("/dog")
})
// UPDATE - PUT - UPDATE A Dog
router.put("/:id", async (req, res) => {
// get the id from the url
const id = req.params.id
// make sure adopted is a boolean
req.body.adopted = req.body.adopted === "on" ? true : false
// use model.findByIdAndUpdate(id, updatedObject) to update dog
await Dog.findByIdAndUpdate(id, req.body).catch(catcher(res))
// redirect the user back to the index page
res.redirect("/dog")
})
// CREATE - POST - CREATE A Dog
router.post("/", async (req, res) => {
// turn the adopted property into a BOOLEAN
// EXPRESSION ? TRUE : FALSE
req.body.adopted = req.body.adopted === "on" ? true : false
// Use model.create(newItem) to create a new dog
await Dog.create(req.body).catch(catcher(res))
// SEND USER BACK TO THE INDEX PAGE
res.redirect("/dog") // get => /dog
})
// EDIT - GET - RENDER FORM TO UPDATE A DOG
router.get("/:id/edit", async (req, res) => {
// get the index of the specified fruit
const id = req.params.id
// get the dog using the index using model.findById(id)
const dog = Dog.findById(id).catch(catcher(res))
// render the template, pass the fruit and index
res.render("dog/edit.ejs", { dog, id })
})
// SHOW - GET - SHOWS ONE FRUIT - /dog/:id
router.get("/:id", async (req, res) => {
// grab the id from the url
const id = req.params.id
// create a variable with the dog specified
const dog = Dog.findById(id).catch(catcher(res))
// render a template with the dog
res.render("dog/show.ejs", { dog, id })
})
// EXPORT OUR ROUTER, The register it in server.js app.use("/dog", dogRouter)
module.exports = router
///////////////////////////////////
//EXPRESS REFERENCE
// Express Video 1: https://youtu.be/6eW8cHXg7ow
// Express Video 2: https://youtu.be/sTseIaapIBM
//////////////////////////////////
require("dotenv").config() // <--- load environmental variables from .env file
const express = require("express"); //<--- import express library
const morgan = require("morgan"); // <--- import morgan library for logging
const cors = require("cors"); // <---- import cors middleware for cors headers
const Dog = require("./models/dog.js"); // hypothetical Dog model made with Mongo/Mongoose
// create express application
const app = express();
// Express Middleware, registered using "use" method
app.use(cors()); // set cors headers so frontend app can make requests to api without cors errors
app.use(morgan("dev")); // server logging for debugging
app.use(express.json()); //middleware for parsing incoming JSON request bodies
app.use(express.urlencoded({ extended: false })); // middleware for parsing urlencoded bodies from html forms
app.use(express.static("public")); // middleware to statically serve files from a "public" folder
// root route, returning hello world as text
app.get("/", (req, res) => {
res.send("Hello World");
});
// Mongoose code can be written using callbacks, async/await or .then, examples of each below
// Index Route - Return All Dogs as JSON
// Using Mongoose with Async/Await
app.get("/dogs", async (req, res) => {
// Try/Catch block for error handling
try {
const allDogs = await Dog.find({}); // query all dogs
res.json(allDogs); // send all dogs back as json
} catch (error) {
res.status(400).json(error); // if error, send error back as json
}
});
// Show Route - Return a Single Dog as JSON
// Using Mongoose with .then syntax
app.get("/dogs/:id", (req, res) => {
Dog.findById(req.params.id) // pass the id from params to find dog by it's DB id
.then((dog) => {
res.json(dog);
}) // send dog as json
.catch((error) => {
res.status(400).json(error);
}); // if query errors send error as json
});
// Create Route - Create a dog from data in request body
// using mongoose with callback syntax
app.post("/dogs", (req, res) => {
// create a new dog from the request body, then in callback return new dog as json
Dog.create(req.body, (error, success) => {
if (error) {
res.status(400).json(error); // return error from json
} else {
res.json(success); // send back dog from successful creation
}
});
});
// Update Route - update a dog from data in the request, which dog based on param
// using async/await
app.put("/dogs/:id", async (req, res) => {
// get id
const id = req.params.id;
// try/catch block for error handling
try {
// update dog, pass new option to get back updated version
const updatedDog = await Dog.findByIdAndUpdate(id, req.body, { new: true });
res.json(updatedDog); // return updated dog as json
} catch (error) {
res.status(400).json(error);
}
});
// Destroy Route - delete a dog, which dog based on param
// using async/await
app.delete("/dogs/:id", async (req, res) => {
// get id
const id = req.params.id;
// try/catch block for error handling
try {
// delete dog and save deleted dog in a variable
const deletedDog = await Dog.findByIdAndRemove(id);
res.json(deletedDog); // return updated dog as json
} catch (error) {
res.status(400).json(error);
}
});
// Turning on the application server, setting it to listen to the
// environment variable "PORT"
const PORT = process.env.PORT || 4000 // use PORT env variable or 4000 if doesn't exist
app.listen(PORT, () => console.log(`Listening on port ${PORT}`))
//////////////////////////////////
// Mongo/Mongoose Reference
// Video: https://youtu.be/_nvIGmI_zS0
/////////////////////////////////
require("dotenv").config() // <-- load ENV variables from .env file
const mongoose = require("mongoose")
// get database url from env variables
const DATABASE_URL = process.env.DATABASE_URL
// Mongoose config object to avoid deprecation warnings
const config = {useNewUrlParser: true, useUnifiedTopology: true}
// Connect to Mongo Database
mongoose.connect(DATABASE_URL, config)
// Setup Events for when connection opens and close
mongoose.connection
.on("open", () => console.log("Mongo Connection is Open"))
.on("close", () => console.log("Mongo Connection is Closed"))
.on("error", (error) => console.log("error ------- \n", error, "\n error ------- "))
// Pull out the Schema class and model functions from mongoose
const {Schema, model} = mongoose
// create a Schema that describes the shape our Dog data model
// we'll also togged on "created_at" and "updated_at" timestamps
const DogSchema = new Schema({
name: {type: String, required: false, unique: false},
age: {type: Number, required: false, unique: false}
}, {timestamps: true})
// Create a Dog model we can then use in server routes to interact with database
const Dog = model("dog", DogSchema)
// export the model to be used in other files
module.exports = Dog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment