Skip to main content

Two Model CRUD App - No relationship - First Model

Lesson Objectives

  1. Init Directory
  2. Start express
  3. Create Home page
  4. Create Authors Index
  5. Create Authors New Page
  6. Set up Author Model
  7. Create Authors Post Route
  8. Show Authors on Index Page
  9. Create Authors Show Page
  10. Create Authors Delete Route
  11. Create Authors Edit Page
  12. Create Authors Put Route

Init Directory

  1. mkdir student_examples/blog
  2. cd student_examples/blog
  3. npm init
    • make entry point server.js
  4. npm install express --save
  5. touch server.js

Start express

server.js:

server.js
const express = require("express");
const app = express();

app.listen(3000, () => {
console.log("listening....");
});

Create Home page

  1. npm install ejs --save
  2. mkdir views
  3. touch views/index.ejs

views/index.ejs:

views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Welcome to the Blog</h1>
<nav>
<ul>
<li>
<a href="/authors">Authors</a>
</li>
<li>
<a href="/articles">Articles</a>
</li>
</ul>
</nav>
</header>
</body>
</html>

server.js:

server.js
app.get("/", (req, res) => {
res.render("index.ejs");
});

Create Authors Index

  1. mkdir views/authors
  2. touch views/authors/index.ejs

views/authors.ejs:

views/authors.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Authors</h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/authors/new">Create a new Author</a>
</li>
</ul>
</nav>
</header>
</body>
</html>
  1. mkdir controllers
  2. touch controllers/authors.js

controllers/authors.js:

controllers/authors.js
const express = require("express");
const router = express.Router();

router.get("/", (req, res) => {
res.render("authors/index.ejs");
});

module.exports = router;

Use the controller in server.js:

server.js
const authorsController = require("./controllers/authors.js");
app.use("/authors", authorsController);

Create Authors New Page

touch views/authors/new.ejs

views/authors/new.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Create an Author</h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/authors">Authors Index</a>
</li>
</ul>
</nav>
</header>
<main>
<form action="/authors" method="POST">
<input type="text" name="name" />
</form>
</main>
</body>
</html>

create route in controllers/authors.js

controllers/authors.js
router.get("/new", (req, res) => {
res.render("authors/new.ejs");
});

Connect to mongo

  1. npm install mongoose --save
  2. Connect in server.js
server.js
const mongoose = require("mongoose");
//...
//...farther down the page
mongoose.connect("mongodb://localhost:27017/blog");

mongoose.connection.once("open", () => {
console.log("connected to mongo");
});

Set up Author Model

  1. mkdir models
  2. touch models/authors.js
models/authors.js
const mongoose = require("mongoose");

const authorSchema = mongoose.Schema({
name: String,
});

const Author = mongoose.model("Author", authorSchema);

module.exports = Author;

Create Authors Create Route

  1. use body parser in server.js
server.js
app.use(express.urlencoded({ extended: false }));

controllers/authors.js

controllers/authors.js
const Author = require("../models/authors.js");
//...
//...farther down the page
router.post("/", async (req, res) => {
try {
const createdAuthor = await Author.create(req.body);
res.redirect("/authors");
} catch (error) {
console.log(error);
};
});

Show Authors on Index Page

controllers/authors.js:

controllers/authors.js
router.get("/", async (req, res) => {
try {
const foundAuthors = await Author.find({});
res.render("authors/index.ejs", {
authors: foundAuthors,
});
} catch (error) {
console.log(error);
};
});

views/authors/index.ejs:

views/authors/index.ejs
<main>
<h2>List of Authors</h2>
<ul>
<% for(let i = 0; i < authors.length; i++){ %>
<li>
<a href="/authors/<%=authors[i]._id%>"><%=authors[i].name%></a>
</li>
<% } %>
</ul>
</main>

Create Authors Show Page

touch views/authors/show.ejs

views/authors/show.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Show Page for <%=author.name%></h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/authors">Author Index</a>
</li>
</ul>
</nav>
</header>
<main>
<section>
<h2>Author Attributes:</h2>
<ul>
<li>Name: <%=author.name%></li>
</ul>
</section>
</main>
</body>
</html>

towards the bottom controllers/authors.js:

controllers/authors.js
//avoid this handling /new by placing it towards the bottom of the file
router.get("/:id", async (req, res) => {
try {
const foundAuthor = awai Author.findById(req.params.id);
res.render("authors/show.ejs", {
author: foundAuthor,
});
} catch (error) {
console.log(error);
};
});

Create Authors Delete Route

  1. npm install method-override --save
  2. use method-override in server.js:
server.js
const methodOverride = require('method-override')

app.use(methodOverride('_method'));

controllers/authors.js:

controllers/authors.js
router.delete("/:id", async (req, res) => {
try {
const removedAuthor = await Author.findByIdAndRemove(req.params.id);
res.redirect("/authors");
} catch (error) {
console.log(error);
};
});

views/authors/show.ejs

views/authors/show.ejs
<section>
<form action="/authors/<%=author._id%>?_method=DELETE" method="post">
<input type="submit" value="Delete Author" />
</form>
</section>

Create Authors Edit Page

Create a link on views/authors/show.ejs:

views/authors/show.ejs
<section>
<a href="/authors/<%=author._id%>/edit">Edit</a>
</section>

controllers/authors.js

controllers/authors.js
router.get("/:id/edit", async (req, res) => {
try {
const foundAuthor = await Author.findById(req.params.id);
res.render("authors/edit.ejs", {
author: foundAuthor,
});
} catch (error) {
console.log(error);
};
});

touch views/authors/edit.ejs

views/authors/edit.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<header>
<h1>Edit <%=author.name%>'s Info</h1>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/authors">Authors Index</a>
</li>
</ul>
</nav>
</header>
<main>
<h2>Author Attributes:</h2>
<form action="/authors/<%=author._id%>?_method=PUT" method="post">
<input type="text" name="name" value="<%=author.name%>" /><br />
<input type="submit" value="Update Author" />
</form>
</main>
</body>
</html>

Create Authors Put Route

controllers/authors.js:

controllers/authors.js
router.put("/:id", async (req, res) => {
try {
const updatedAuthor = await Author.findByIdAndUpdate(req.params.id, req.body);
res.redirect("/authors");
} catch (error) {
console.log(error);
};
});