In this example we will see the interactivity between MongoDB and Nodejs.
We will create a “Post It” / “Sticky Notes” application in Nodejs and save the data in MongoDb.
Please check the other post for setting up mongodb with nodejs for this example..
Install npm packages for express, ejs, async :
npm install express ejs async
Now if you have followed back from the first article, then add the following methods to postitdb.js
// create the schema
var PostItSchema = new Schema(
{
ts : { type: Date, default: Date.now },
author : String,
note : String
});
// register the schema
mongoose.model('PostIt',PostItSchema);
// create instance of the model
var Note = mongoose.model('PostIt');
exports.emptyNote = { "_id": "", author: "", note:""};
// define and export the add function to add a new note
exports.add = function(author, note, callback)
{
var newNote = new Note();
newNote.author = author;
newNote.note = note;
// to save a new note all you need to do it call save on it
newNote.save(function(err)
{
if (err)
{
util.log('FATAL ' + err);
callback(err);
}
else
{
callback(null);
}
});
};
// define and export the delete function
exports.delete = function(id,callback)
{
// find the note by id then delete it by calling remove
exports.findNoteById(id, function(err,doc)
{
if(err)
{
callback(err);
}
else
{
util.log(util.inspect(doc));
doc.remove();
callback(null);
}
});
};
// define and export the edit function
exports.edit = function(id, author, note, callback)
{
// fine the note by id and edit it then save the changes.
exports.findNoteById(id, function(err, doc)
{
if (err)
{
callback(err);
}
else
{
doc.ts = new Date();
doc.author = author;
doc.note = note;
doc.save(function(err)
{
if(err)
{
util.log('FATAL ' + err);
callback(err);
}
else
{
callback(null);
}
});
}
});
};
// define and export allNotes function
exports.allNotes = function(callback)
{
// we will get all notes from the db if we do not give any conditional expression
Note.find({}, callback);
};
// define and export forAll function
exports.forAll = function(doEach, done)
{
// we will get all notes from the db if we do not give any conditional expression
// then invoke doEach function on every row
Note.find({}, function(err, docs)
{
if(err)
{
util.log('FATAL ' + err);
done(err,null);
}
docs.forEach(function(doc)
{
doEach(null,doc);
});
done(null);
});
};
// define findNoteById and exports it.
var findNoteById = exports.findNoteById = function(id, callback)
{
Note.findOne({_id: id} , function(err,doc)
{
if (err)
{
util.log('FATAL ' + err);
callback(err,null);
}
callback(null,doc);
});
};
Now lets create app.js which holds all the logic for routing and connecting different bits to each other.
var util = require('util');
var url = require('url');
var express = require('express');
var postitdb = require('./postitdb');
var app = express.createServer();
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.register('.html',require('ejs'));
app.set('views',__dirname + '/views');
app.set('view engine','ejs');
var parseUrlParams = function(req,res,next)
{
req.urlP = url.parse(req.url,true);
next();
}
var checkAccess = function(req,res,next)
{
// a logged-in user will have "AOK" set in his cookies
if (!req.cookies || !req.cookies.notesaccess || req.cookies.notesaccess !== "AOK")
{
res.redirect('/login');
}
else
{
next();
}
};
postitdb.connect(function(error)
{
if (error) throw error;
});
app.on('close', function(errno)
{
postitdb.disconnect(function(err) {} );
});
app.get('/', function (req,res) { res.redirect('/view'); } );
app.get('/login', function(req,res)
{
res.render('login.html', { title: "Notes LOGIN" });
});
app.post('/login', function(req,res)
{
if (req.body.username== "gabbarsingh" && req.body.pwd=="kalia")
{
res.cookie('notesaccess','AOK');
res.redirect('/view');
}
else
{
util.log('Cannot match username and password');
}
});
app.get('/view', parseUrlParams, checkAccess, function (req,res)
{
postitdb.allNotes(function(err, notes)
{
if(err)
{
util.log('ERROR ' + err);
throw err;
}
else
{
res.render('viewnotes.html', { title : "Notes", notes: notes });
}
});
});
app.get('/add', parseUrlParams, checkAccess, function(req,res)
{
res.render('addedit.html', { title : "Notes", postpath: '/add', note: postitdb.emptyNote});
});
app.post('/add', checkAccess, function(req,res)
{
postitdb.add(req.body.author, req.body.note, function(error)
{
if (error) throw error;
res.redirect('/view');
});
});
app.get('/del', parseUrlParams, checkAccess, function(req,res)
{
postitdb.delete(req.urlP.query.id, function(error)
{
if(error) throw error;
res.redirect('/view');
});
});
app.get('/edit', parseUrlParams, checkAccess, function(req,res)
{
postitdb.findNoteById(req.urlP.query.id, function(error, note)
{
if (error) throw error;
res.render('addedit.html', {title : "Notes", postpath:'/edit', note: note });
});
});
app.post('/edit', checkAccess, function(req,res)
{
postitdb.edit(req.body.id, req.body.author, req.body.note, function(error)
{
if (error) throw error;
res.redirect('/view');
});
});
app.listen(3000);
Now we just need to give html files for rendering the output.
Create a views directory that will be used by ejs to render html from html files from this directory as registered earlier.
mkdir views
Create all the html files mentioned below in “views” directory.
layout.html
<html>
<head><title><%= title %></title></head>
<body>
<h1><%= title %></h1>
<p><a href='/view'>View</a> | <a href='/add'>Add</a></p>
<%- body %>
</body>
</html>
viewnotes.html
<table><% notes.forEach(function(note)
{ %>
<tr><td>
<p><%= new Date(note.ts).toString() %>: by <b> <%= note.author %></b></p>
<p><%= note.note %></p>
</td>
<td>
<form method='GET' action='/del'>
<input type='submit' value='Delete'/>
<input type='hidden' name='id' value='<%= note._id %>' />
</form>
<br/>
<form method='GET' action='/edit'>
<input type='submit' value='Edit' />
<input type='hidden' name='id' value='<%= note._id %>' />
</form>
</td>
</tr>
<% }); %></table>
addedit.html
<form method='POST' action='<%= postpath %>'>
<% if(note)
{ %>
<input type='hidden' name='id' value='<%= note._id %>' />
<% } %>
<input type='text' name='author' value='<%= note.author %>' />
<br/>
<textarea rows=5 cols=40 name='note'>
<%= note.note %>
</textarea>
<br/>
<input type='submit' value='Submit' />
</form>
login.html
<form method='POST' action='/login'>
<p>Click the <i>Login</i> to log in.</p>
<table>
<tr>
<td>Username: </td>
<td><input type='text' name='username' length=30 /></td>
</tr>
<tr>
<td>Password: </td>
<td><input type='password' name='pwd' length=30 /></td>
</tr>
<tr>
<td><input type='submit' value='Login' /></td>
<td><input type='reset' value='Clear' /></td>
</tr>
</table>
</form>
That is all you need, and now you can run the application using
node app
And visit the url : http://localhost:3000, Voila!