Last active
June 14, 2023 14:39
-
-
Save AlexMercedCoder/b83334dc4710b8f37e6b265e0a93c2e9 to your computer and use it in GitHub Desktop.
Reference For ExpressJS and Mongo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////// | |
// ./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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////// | |
//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}`)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////// | |
// 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