Blog

CRUD (Create, Read, Update, Delete) with Modularized Node.js, MongooseJS, and MongoDB
Posted on July 22, 2015 in MongoDB, Node.js by Matt Jennings

Directory Structure Image with the Node Modules Below Installed in the node_modules directory:

  • body-parser
  • ejs
  • express
  • mongoose

modularized node.js directory structure

/package.json

{
  "name": "modularized-mongoose-dashboard",
  "version": "0.0.1",
  "description": "modularized mongoose dashboard using node.js",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/Hollyw00d/modularized-mongoose-dashboard"
  },
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "body-parser": "1.13.x",
    "ejs": "2.3.x",
    "express": "4.13.x",
    "mongoose": "4.0.x"
  }
}

/server.js

// Require path
var path = require("path");

// Require epxress and create express app
var express = require("express");
var app = express();

// Require body-parser to be able to send POST data
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded( {extended: true} ));

// Link to mongoose.js
require("./server/config/mongoose.js");

// Link to routes.js and pass in "app" variable
require("./server/config/routes.js")(app);

// Static content
app.use(express.static(path.join(__dirname + "/client/static")));

// Set up views directory & ejs
app.set("views", path.join(__dirname + "/views"));
app.set("view engine", "ejs");

// Listen on port 8000
app.listen(8000, function() {
    console.log("Node.js is running on port 8000");
});

MongooseJS: /config/mongoose.js

// Require mongoose
var mongoose = require("mongoose");

// Require file-system so we can load, ready, require
// all of the model files
var fs = require("fs");

// Connect to "animals" DB
mongoose.connect("mongodb://localhost/animals");

// Specify the path to all of the models
var modelsPath = __dirname + "/../models";

// Read all of the files in the modelsPath AND
// for each one check if it is a javascript file
// before requiring it
fs.readdirSync(modelsPath).forEach(function(file) {
    if(file.indexOf(".js") > 0) {
        require(modelsPath + "/" + file);
    }
});

Routes: /config/routes.js

// Show export to "animalsController" controller
var showanimals = require("../controllers/showanimals.js");

// Pass routes from this file to server.js
module.exports = function(app) {

    // Home page
    app.get("/", function(req, res) {
        showanimals.show(req, res);
    });

    // Form page to add new animals
    // to MongoDB collection
    app.get("/mongooses/new", function(req, res){
        showanimals.newanimalform(req, res);
    });

    // Show a single animal
    app.get("/mongooses/:id", function(req, res) {
        showanimals.showSingleAnimal(req, res);

    });

    // Update a single animal
    app.get("/mongooses/:id/edit", function(req, res) {
        showanimals.updateSingleAnimal(req, res);
    });

    // Route to add an animal to DB
    app.post("/mongooses", function(req, res) {
        showanimals.addanimal(req, res);
    });


    // Route to update a single
    // animal document
    app.post("/mongooses/:id", function(req, res) {
        showanimals.executeUpdateAnimal(req, res);
    });

// Route to delete a single
// animal document
    app.get("/mongooses/:id/destroy", function(req, res) {

        showanimals.deleteAnimal(req, res);

    });

}

Controller: /controllers/showanimals.js

// Require mongoose
var mongoose = require("mongoose");

// Load models by name
var Animal = mongoose.model("Animal");
var AddAnimal = mongoose.model("AddAnimal");
var UpdateAnimal = mongoose.model("UpdateAnimal");

// Create a controller object to use for export
var showanimalsController = {};

// Call the "show" method for the controller object
showanimalsController.show = function(req, res) {

    Animal.find({}).exec(function (err, animals) {
        if (err) {
            console.log("Error:", err);
        }
        else {
            res.render("../client/views/index", {animals: animals});
        }
    });
};

// Go to form to add a new animal to
// the MongoDB "animals" collection
showanimalsController.newanimalform = function(req, res) {
    res.render("../client/views/new");
};

// Add a new animal into the MongoDB
// the MongoDB "animals" collection
showanimalsController.addanimal = function(req, res) {
    // Create a new "animal" object
    // to save
    var animal = new Animal(req.body);

    // Save a single animal into MongoDB
    animal.save(function(err) {
        // Show form data posted
        //console.log("POST DATA", req.body);

        if(err) {
            console.log("Animal not added to 'animals' collection.");

            res.render("/mongooses/new");
        }
        else {
            console.log("Successfully updated an animal.");
            res.redirect("/");
        }
    });
};

// Show a single animal
showanimalsController.showSingleAnimal = function(req, res) {

    // Show one "animal" document based
    // on said document's "_id"
    Animal.findOne({_id: req.params.id}, function(err, animal) {

        res.render("../client/views/animal", {animal: animal});
    });

};

// Update single animal document
showanimalsController.updateSingleAnimal = function(req, res) {

    Animal.findOne({_id: req.params.id}, function(err, animal) {

        console.log("Edit an animal");

        res.render("../client/views/editanimal", {animal: animal});
    });
};

// Update a single animal name controller method
showanimalsController.executeUpdateAnimal = function(req, res) {

    // Update a single animal
    Animal.update({_id: req.params.id}, {$set: {name: req.body.name} }, function(err) {

        // If error exists display it
        if(err) {
            console.log("Update Animal Error:", err);
        }
        // Else update a single animal name
        else {
            console.log("New Animal Name:", req.body.name);
            res.redirect("/");
        }

    });

};

// Delete a single animal document method
showanimalsController.deleteAnimal = function(req, res) {

    // Delete a single animal document
    // and redirect to the home page
    Animal.remove({_id: req.params.id}, function(err) {

        // If error exists display it
        if(err) {
            console.log("Delete Animal Error", err);
        }
        else {
            console.log("Animal deleted!");
            res.redirect("/");
        }

    });
};

module.exports = showanimalsController;

Model: /models/showanimal.js

// Require mongoose
var mongoose = require("mongoose");

// Create new schemas for
// CRUD animals into/from database
var AnimalSchema = new mongoose.Schema({
    name: String,
    updated_at: {type: Date, default: Date.now}
});

// Schema for adding animals into database
var AddAnimalSchema = new mongoose.Schema({
    name: String,
    updated_at: {type: Date, default: Date.now}
});

// Schema for updating a single animal
var UpdateAnimalSchema = new mongoose.Schema({
    name: String,
    updated_at: {type: Date, default: Date.now}
});

// Connect my collection and model schemas
mongoose.model("Animal", AnimalSchema);
mongoose.model("AddAnimal", AddAnimalSchema);
mongoose.model("UpdateAnimal", UpdateAnimalSchema);

View to Show All Animals from MongoDB animals Collection: /client/views/index.ejs

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mongoose Dashboard</title>
    <link rel="stylesheet" type="text/css" href="css/styles.css"/>
</head>
<body>

<div id="wrapper">

    <h1>Show all Documents in <em>animals</em> MongoDB</h1>

    <ul>
        <% for(var i = animals.length -1; i > -1; i--) {%>
            <li><strong>Name:</strong> <a href="mongooses/<%= animals[i]._id %>"><%= animals[i].name %></a></li>
        <% } %>
    </ul>

    <p><a href="mongooses/new">Insert New Animal into Database</a></p>

</div>

</body>
</html>

View to Add (Create) an Animal Into Collection: /client/views/new.ejs

<div id="wrapper">

    <h1>Insert a New Animal into the <em>animals</em> MongoDB</h1>

    <form action="/mongooses" method="post">
        <p><label for="name">Animal Name: </label><input type="text" name="name"/></p>
        <p><input type="submit" value="Submit"/></p>
    </form>

    <p><a href="/">Go Home</a></p>

</div>

View to Show a Single Animal Document: /client/views/animal.ejs

<div id="wrapper">

    <h1>Show the <em><%= animal.name %></em> Document</h1>

    <p><strong>Name:</strong> <%= animal.name %></p>

    <p><a href="/mongooses/<%= animal._id %>/edit">Update animal name</a><br /><br />
        <a href="/mongooses/<%= animal._id %>/destroy">Delete animal</a></p>

    <p>&nbsp;</p>
    <p><a href="/">Go Home</a></p>

</div>

View to Update a Single Animal Document: /client/views/editanimal.ejs

<div id="wrapper">

    <h1>Update the <em><%= animal.name %></em> Document</h1>

    <form action="/mongooses/<%= animal._id %>" method="post">
        <p><label for="name"><strong>Name:</strong></label>
        <input type="text" name="name" value="<%= animal.name %>"/></p>
        <p><input type="submit" value="Update"/></p>
    </form>

    <p><a href="/">Go Home</a></p>

</div>

Leave a Reply