Create a TODO App in 15 minutes using Express4, Node.js, Mongoose
This is a beginner level app to get started with Express4 basics, using Mongoose and its basic querying model.
We are going to Create a TODO app that does CRUD operations that i.e
PART I : BASIC SETUP
1) Install Node and Node Package Manager (NPM)
Installing Node and NPM is pretty straightforward,
Go to http://nodejs.org/download/ and download either source-code or executable as per your system.
As I am on mac, I used Homebrew to install node and npm
brew install node
Node comes by default with NPM which is node package manager.
Test the installation
> node -v
v0.10.31
2) Install Express, Mongoose, Nodemon
Express : Most popular Web Framework based out of Node and used by many prominent application like Storify, New Myspace etc..
npm install -g express-generator
express-generator is a generator app created by express team that generates express project with express and other required middlewares to get started.
Mongoose : Mongoose provides a Wrapper around MongoDB that helps to define schema based model, built-in type casting, validations, and various other quick functions.
npm install -g mongoose
Make sure you have MongoDB installed plus Up and running.
Or you can follow instructions here http://docs.mongodb.org/manual/installation/
Nodemon : It monitors for any changes in your node.js application and automatically restart the server - perfect for development
npm install -g nodemon
3) Generating Express App
After all the essential packages are installed, lets start creating app.
$> express myapp
create : myapp create : myapp/package.json create : myapp/app.js create : myapp/public create : myapp/public/javascripts create : myapp/public/images create : myapp/public/stylesheets create : myapp/public/stylesheets/style.styl create : myapp/routes create : myapp/routes/index.js create : myapp/views create : myapp/views/index.jade create : myapp/views/layout.jade install dependencies: $ cd myapp && npm install run the app: $ DEBUG=myapp node app
After MyApp is created, open myapp in your favorite editor and edit package.json to add mongoose to package dependencies.
{
"name": "myapp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"express": "~4.2.0",
"static-favicon": "~1.0.0",
"morgan": "~1.0.0",
"cookie-parser": "~1.0.1",
"body-parser": "~1.0.0",
"debug": "~0.7.4",
"jade": "~1.3.0",
"mongoose": "*"
}
}
Next, cd to myapp dir and install packages. It will get installed in node_modules directory.
> cd myapp
> npm install
........
Now our basic setup is done, lets move onto next part.
PART II : CREATING APP
1) Create TODO Model Schema ( db.js )
Create a File called db.js that contains the schema for Todo Model we will use. It will have basic fields like content, updated_at.
The content will look like this.
var mongoose = require( 'mongoose' );
var Schema = mongoose.Schema;
var Todo = new Schema({
content : { type: String, required: true },
updated_at : Date
});
mongoose.model( 'Todo', Todo );
mongoose.connect( 'mongodb://localhost/express-myapp' );
Here, we first require mongoose in-order to use it. We create mongoose schema object which is defined by mongoose.
Schema and create Todo Schema object with field types and basic validation rules like required so that we do not insert blank entries to mongo document.
We define Model object name as Todo for referencing in our app.
In last line we add connect command as provided by mongoose.
Note: We haven't created Mongo database named express-myapp yet that is because we don't need to as mongoose will automatically take care of creating it, inserting it after validating rules that we define.
Mongoose definitely gives us that power to control database through code. It is very similar to ActiveRecord Gem in Rails framework.
Once this is done, add a line at top of app.js
require('./db');
var express = require('express');
....
app.use('/', routes);
...
We already have a routes defined that points to routes/index.js file where we can define relevant routes for our app.
2) CRUD : Creating New Todo Item page
Now we have our Todo schema setup, lets start by adding a form that accepts content and creates a todo item.
To do that open routes/index.js and add a "/new" route that renders a form submission page.
// new todo form router.get('/new', function(req, res) { res.render('new', { title: ': new' }); });
Create a jade view named new.jade inside views folder i.e views/new.jade
extends layout
block content div.page-header form.form-horizontal(action="/create", method="post") div.form-group.col-sm-10 input.form-control(type="text", name="content", placeholder="Content") div.form-group button.btn.btn-default(type="submit") Add
We point the action to /create which is shown next.
Note: Jade is similar to Haml and uses space indentation to parse and render html. For more info jade-lang.com/reference
Now, Open up the browser to localhost:3000/new and it shows a simple content input with Add button.
CRUD : Create Action
Create Action will take form data through a POST request. The request object posted contains the form-data inside body attribute and can be accessed via req.body.content.
Inside routes/index.js we add a create route below.:
//create new todo router.post('/create', function(req, res) { // add TODO's to db new Todo({ content : req.body.content, updated_at : Date.now() }).save( function( err, todo, count ){ res.redirect( '/' ); }); });
Here, the route listen to post request and creates a new Todo object with content as the non-blank, submitted todo item.
On Save Callback, we redirect the page to index route.
CRUD : Index Route
Now we have a form and create route setup. You can try adding few todo items.
To view them on index page, change the index route to:
routes/index.js
/* GET home page. */ router.get('/', function(req, res) { // show all todos relative to user Todo.find().sort('-updated_at').find( function ( err, todos, count ){ res.render( 'index', { title : ': ALL', todos : todos }); }); });
Here we find all the todo items, sort it in descending order of creating and render todos object to index view.
To display them, change the index view to :
extends layout
block content - each todo in todos div.panel.panel-default div.panel-body h3= todo.content small.pull-right a(href='/ed/#{todo._id}') edit a(href='/del/#{todo._id}') delete
This will render all the created todos on index page.
Note we have also created edit and delete link on right.
CRUD : Edit/Update
Similar to new, we create a edit form view with value already poplulated.
Create views/Edit.jade as :
extends layout
block content div.page-header form.form-horizontal(action="/update", method="post") div.form-group.col-sm-10 input.form-control.hidden(value="#{todo._id}", name="id") input.form-control(type="text", name="content", placeholder="Content", value="#{todo.content}") div.form-group button.btn.btn-default(type="submit") Update
Add edit route to render view :
// edit todo form router.get('/ed/:id', function(req, res) { Todo.findById(req.params.id, function (err, todo) { res.render('edit', { title: ': edit', todo : todo }); }); });
Here we are paring req param id value and retrieving todo object using
findbyId method and passing it to edit view above.
CRUD : Update Route
Very similar to create method we find the object and update it as below :
// update todo form router.post('/update', function(req, res) { console.dir(req.body); Todo.findById(req.body.id, function (err, todo) { todo.content = req.body.content; todo.save( function ( err, todo ){ res.redirect( '/' ); }); }); });
CRUD : Delete Route
Completing the delete route which is pretty straightforward.
// delete todo router.get('/del/:id', function(req, res) { Todo.findById(req.params.id, function (err, todo) { todo.remove( function ( err, todo ){ res.redirect( '/' ); }); }); });
For bootstrap version : I have used lumen theme which is available
bootswatch.com/lumen/
Gist : https://gist.github.com/dhirajbajaj/c6140f05d92b88478fa7
















