Express: Connecting Handlebars to MongoDB - tdkehoe/blog GitHub Wiki
#Reading From the Database To a .HBS Template
Handlebars uses templates that look like HTML files but end in .hbs. For example:
<div>
<ul>
{{#fromDB}}
<li>{{quote}}</li>
<form action="/userlist/{{_id}}/delete" method="POST">
<input class="delete-button" type="submit" name="delete" value="DELETE"></input>
</form>
{{/fromDB}}
</ul>
</div>
The items in double curly braces are handlebars statements. They are commands and variables. This page has two Handlebars commands and two handlebars variables:
The Handlebars commands are {{#fromDB}} and its closing statement {{/fromDB}}.
The Handlebars variables are {{quote}} and {{_id}}.
The Handlebars commands link to the database, via Express middleware. index.js includes the route /userlist:
router.get('/userlist', function(req, res) {
var collection = req.db.get('quotes');
collection.find({}, {}, function(err, docs) {
var obj = {
fromDB: docs,
title: "This is a title of the page"
}
res.render('userlist', obj);
});
});
The first line specifies that this is a router for GET requests from the browser when loads /userlist.
The second line points the variable collection to a request to the database to get the collection quotes.
The third line does a find operation on the collection we specified in the second line. The first argument is an empty object, which tells the database to return all documents (records) in the collection. The second argument is also an empty object, which tells the database to return all fields (instead of doing a projection that limits the fields returned). These two empty objects could be left out, e.g., collection.find(), except that we want to run a callback function so we need the two empty objects as placeholders before the callback function.
The callback function in the third line has two parameters. The err error parameter is unused. The docs parameter is what the database returns. In MongoDB, records are called documents so an array of records can be called docs. The database returns an array of objects, with the data we requested.
The fourth line creates an object that we will call our data object. The data object contains the values we want Handlebars to insert the variables on our .hbs page.
On the fifth line, the first property is the docs that came from the database. Here the key is called fromDB to indicate that these are the docs that came from the database.
You can put other things into the data object. On the sixth line we add a kadigan value to fill the Handlebars variable {{title}} on the .hbs page.
The last line of this route sends an HTTP response that renders an HTML page. res.render takes two arguments because it combines two items to create an HTML page. The first argument here is 'userlist', which is the file userlist.hbs (How does Express know this?) The second argument is the data object. Handlebars is now able to fill its variables on userlist.hbs with values from the database.
(Are Handlebars and npm hbs the same thing?)
Handlebars takes all variables and converts them to strings.
#Insert a New Document Into the Database From a .hbs Page
router.post('/addquote', function(req, res) {
var quote = req.body.quote;
var collection = req.db.get('quotes');
collection.insert({"quote": quote}, function (err, doc) {
if (err) {
res.send("There was a problem adding the information to the database.");
}
else {
res.redirect("/userlist"); // works with or without preceding slash
}
});
});
The first line specifies that this is a route with a POST request on the '/addquote' route, with a callback function taking HTML request and response as parameters.
The second line sets quote as the quote section of the HTTP request body.
The third line sets collection as a HTTP request to the database collection 'quotes'.
The fourth line inserts data into our database collection. quote is inserted into the field "quote". The callback function has two parameters. The first is the error, which we handle on the next few lines. The second parameter is the document we're inserting into, which we don't use.
The last line is a redirect. POST methods always end in redirects, not rendered pages, so that the user doesn't click the Submit button twice and insert a second record. The redirect works with or without the slash ('userlist' and '/userlist' are the same).