Skip to main content

CRUD App with Mongoose - Create and Read

Lesson Objectives

  1. Initialize a directory
  2. Start express
  3. Create New Route
  4. Create Create Route
  5. Connect Express to Mongo
  6. Create Fruits Model
  7. Have Create Route Create data in MongoDB
  8. Create Index Route
  9. Have Index Route Render All Fruits
  10. Have Create Route redirect to Index After Fruit Creation
  11. Create Show Route
  12. Have Index Page Link to Show Route
  13. Create show.ejs

Initialize a directory

  1. Create a directory for the app in student_examples and cd into it
  2. npm init
  3. npm install express
  4. touch server.js
  5. Edit package.json to have "main": "server.js",

Start express

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

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

Create New Route

server.js
app.get("/fruits/new", (req, res) => {
res.send("new");
});
  1. mkdir views
  2. npm install ejs
  3. touch views/new.ejs
  4. Create the view
views/new.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>New Fruit page</h1>
<form action="/fruits" method="POST">
Name: <input type="text" name="name" /><br />
Color: <input type="text" name="color" /><br />
Is Ready To Eat: <input type="checkbox" name="readyToEat" /><br />
<input type="submit" name="" value="Create Fruit" />
</form>
</body>
</html>

Render the view

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

Create Create Route

server.js
app.post("/fruits/", (req, res) => {
res.send("received");
});
  1. Use express.urlencoded in server.js:
server.js
app.use(express.urlencoded({ extended: true }));

Check to see if req.body works:

server.js
app.post("/fruits/", (req, res) => {
res.send(req.body);
});

Format data properly

server.js
app.post("/fruits/", (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;
}
res.send(req.body);
});

Connect Express to Mongo

  1. npm install mongoose
  2. Inside server.js:
server.js
const mongoose = require("mongoose");

//... and then farther down the file
mongoose.connect("mongodb://localhost:27017/basiccrud", {
useNewUrlParser: true,
});
mongoose.connection.once("open", () => {
console.log("connected to mongo");
});

Create Fruits Model

  1. mkdir models
  2. touch models/fruits.js
  3. Create the fruit schema
models/fruits.js
const mongoose = require("mongoose");

const fruitSchema = new mongoose.Schema({
name: { type: String, required: true },
color: { type: String, required: true },
readyToEat: Boolean,
});

const Fruit = mongoose.model("Fruit", fruitSchema);

module.exports = Fruit;

Have Create Route Create data in MongoDB

Inside server.js:

server.js
const Fruit = require("./models/fruits.js");
//... and then farther down the file
app.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 fruit = await Fruit.create(req.body);
console.log(fruit);
} catch (error) {
console.log(error);
};
});

Create Index Route

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

touch views/index.ejs

views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>Fruits index page</h1>
</body>
</html>

Render the ejs file

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

Have Index Route Render All Fruits

server.js
app.get("/fruits", async (req, res) => {
try {
const allFruits = await Fruit.find({});
res.render("index.ejs", { fruits : allFruits })
} catch (error) {
console.log(error);
};
});

Update the ejs file:

views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Fruits index page</h1>
<ul>
<% for(let i = 0; i < fruits.length; i++){ %>
<li>
The <%=fruits[i].name; %> is <%=fruits[i].color; %>.
<% if(fruits[i].readyToEat === true){ %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
</li>
<% } %>
</ul>
</body>
</html>

Add a link to the create page:

views/index.ejs
<nav>
<a href="/fruits/new">Create a New Fruit</a>
</nav>

Have Create Route redirect to Index After Fruit Creation

Inside the create route

server.js
try {
const createdFruit = await Fruit.create(req.body);
res.redirect("/fruits");
} catch (error) {
console.log(error);
};
views/index.ejs
<li>
The
<a href="/fruits/<%= fruits[i].id %>">
<%= fruits[i].name; %>
</a>
is <%= fruits[i].color; %>.

<% if (fruits[i].readyToEat) { %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
</li>

Create Show Route

server.js
app.get("/fruits/:id", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.send(foundFruit);
} catch (error) {
console.log(error);
};
});

Create show.ejs

  1. touch views/show.ejs
  2. Add HTML
views/show.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Fruits show page</h1>
The <%=fruit.name; %> is <%=fruit.color; %>.
<% if(fruit.readyToEat === true){ %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
<nav>
<a href="/fruits">Back to Fruits Index</a>
</nav>
</body>
</html>

Render the ejs

server.js
app.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);
};
});