Express Router
Lesson Objectives
- Explain What Express.Router does for us
- Create External Controller File for Routes
- Move Server.js Routes to External Controller File
- Require Mongoose in Controller File
- Use Controller File in Server.js
- Remove References to Base of Controller's URLs
Explain What Express.Router does for us
- Our server.js file is getting rather bloated
- express.Router will let us put our routes in a separate file
Create External Controller File for Routes
mkdir controllerstouch controllers/fruits.js- Edit controllers/fruits.js
controller/fruits.js
const express = require("express");
const router = express.Router();
module.exports = router;
Move Server.js Routes to External Controller File
rename app to router
controller/fruits.js
const express = require("express");
const router = express.Router();
router.get("/fruits/new", (req, res) => {
res.render("new.ejs");
});
router.post("/fruits/", async (req, res) => {
if (req.body.readyToEat === "on") {
//if checked, req.body.readyToEat is set to 'on'
req.body.readyToEat = true;
} else {
//if not checked, req.body.readyToEat is undefined
req.body.readyToEat = false;
}
try {
const newFruit = await Fruit.create(req.body);
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
});
router.get("/fruits", async (req, res) => {
try {
const allFruits = await Fruit.find({});
res.render("index.ejs", {
fruits: allFruits,
});
} catch (error) {
console.log(error);
};
});
router.get("/fruits/:id", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.render("show.ejs", {
fruit: foundFruit,
});
} catch (error) {
console.log(error);
};
});
router.delete("/fruits/:id", async (req, res) => {
try {
const removeFruit = await Fruit.findByIdAndRemove(req.params.id);
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
});
router.get("/fruits/:id/edit", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.render("edit.ejs", {
fruit: foundFruit, //pass in found fruit
});
} catch (error) {
console.log(error);
};
});
router.put("/fruits/:id", async (req, res) => {
if (req.body.readyToEat === "on") {
req.body.readyToEat = true;
} else {
req.body.readyToEat = false;
}
// {new: true} tells mongoose to send the updated model into the callback
try {
const updateFruit = await Fruit.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true });
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
});
module.exports = router;
Require Fruit Model in Controller File
controllers/fruits.js
const express = require("express");
const router = express.Router();
const Fruit = require("../models/fruits.js");
//...
The Fruit model is no longer needed in server.js. Remove it:
server.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const methodOverride = require("method-override");
Use Controller File in Server.js
server.js
const fruitsController = require("./controllers/fruits.js");
app.use(fruitsController);
Remove References to Base of Controller's URLs
You can specify when a middleware runs
server.js
const fruitsController = require("./controllers/fruits.js");
app.use("/fruits", fruitsController);
Since we've specified that the controller works with all urls starting with /fruits, we can remove this from the controller file:
controllers/fruits.js
const express = require("express");
const router = express.Router();
router.get("/new", (req, res) => {
res.render("new.ejs");
});
router.post("/", async (req, res) => {
if (req.body.readyToEat === "on") {
//if checked, req.body.readyToEat is set to 'on'
req.body.readyToEat = true;
} else {
//if not checked, req.body.readyToEat is undefined
req.body.readyToEat = false;
}
try {
const newFruit = await Fruit.create(req.body);
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
});
router.get("/", async (req, res) => {
try {
const allFruits = await Fruit.find({});
res.render("index.ejs", {
fruits: allFruits,
});
} catch (error) {
console.log(error);
};
});
router.get("/:id", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.render("show.ejs", {
fruit: foundFruit,
});
} catch (error) {
console.log(error);
};
});
router.delete("/:id", async (req, res) => {
try {
const removedFruit = await Fruit.findByIdAndRemove(req.params.id);
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
});
router.get("/:id/edit", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.render("edit.ejs", {
fruit: foundFruit, //pass in found fruit
});
} catch (error) {
console.log(error);
};
});
router.put("/:id", async (req, res) => {
if (req.body.readyToEat === "on") {
req.body.readyToEat = true;
} else {
req.body.readyToEat = false;
}
//{new: true} tells mongoose to send the updated model into the callback
try {
const updatedFruit = await Fruit.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true });
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
});
module.exports = router;