Skip to main content

Express Router

Lesson Objectives

  1. Explain What Express.Router does for us
  2. Create External Controller File for Routes
  3. Move Server.js Routes to External Controller File
  4. Require Mongoose in Controller File
  5. Use Controller File in Server.js
  6. 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

  1. mkdir controllers
  2. touch controllers/fruits.js
  3. 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;