Alright next step! Now that we can create posts, let's display them.

  1. Create a post
  2. Show all posts and show one post
    1. Make the root route (/) go to the posts#index route render a posts-index template
    2. Style the template and loop over the posts object
    3. Make route to posts#show route (/posts/:id)
    4. Style the template and display the post object
  3. Show one post
  4. Comment on posts
  5. Create subreddits
  6. Sign up and Login
  7. Associate posts and comments with their author
  8. Make comments on comments
  9. Vote a post up
  10. Sort posts by # of votes

Connection Script

You'll need to make a connection to Mongoose from server.js/app/js.

I'm going to encourage the use of promises to handle asynchronous transactions. Mongoose doesn't supply it's own Promise library, instead Mongoose asks you to set a Promise library. The tutorial will use the default JavaScript Promise.

Last, for testing, we can add an error handler for connection errors.

mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost/redditclone', { useMongoClient: true })
mongoose.connection.on('error', console.error.bind(console, 'MongoDB connection Error:'))


Add this to get debug info from Mongoose in the console.

mongoose.set('debug', true)

Posts#Index Route

Let's have the root route (/) render the posts-index template.

Can you get the template to display anything like hello world for example? Once you can we need to now pull the posts out of the database and send them along with the response.

Post.find({}).then((posts) => {
  res.render('posts-index.hbs', { posts })
}).catch((err) => {

In your template can you output the variable {{posts}}?

Styling and Looping Over Posts

Let's go back to our layout template put the whole {{{body}}} object into a div with a container class.

<div class="container">

Now let's put this list of posts into the middle 8 columns of the grid.

<div class="row">
  <div class="col-sm-8 col-sm-offset-2">

Now that we have {{posts}}, we can use handlebar's built in each operator to loop over the posts and display each one.

In each post, let's use bootstrap's list-group and list-group-item classes. Let's display the post title in a lead classed div and add an anchor tag to link to the post's url. Add target="_blank" to the anchor tag so that the url opens in a new tab.

  {{#each posts}}
  <li class="list-group-item">
    <div class="lead">{{this.title}}</div>
    <a href="{{this.url}}" target="_blank">{{this.url}}<a>

Viewing One Post

Now we'd like for each post, when you click on it, to navigate to that particular post's own page.

So let's start with what the user can do - click on a post in the post-index template.

<a href="/posts/{{this._id}}" class="lead">{{this.title}}</a>

Now the title is a link to the show page. If we click it what do we see? No route! Let's fix that.

Posts#Show Route

Now we need the path /posts/:id to resolve to displaying a post-show template. So from inside the posts controller file, we need to have a new GET endpoint.

  app.get('/posts/:id', function (req, res) {
   Post.findById( => {
     res.render('post-show.hbs', { post })
   }).catch((err) => {

Now what happens if we refresh? No template!

Making the Template

Let's get a template in there. As a bare minimum we'll use some bootstrap classes to make things look ok.

<div class="row">
  <div class="col-sm-6 col-sm-offset-3">
    <a href="{{post.url}}" class="lead">{{post.title}}</a>

Now can you see your post? :D


If you have feedback on this tutorial or find any mistakes, please open issues on the GitHub Repository or comment below.

Summer academy

An iOS Development Summer Course

Design, code and launch your own app. Locations in San Francisco and Asia

Find your location

Product College

A computer science college

Graduate into a successful career as a founder or software engineer.

Learn more

Cookies on Make School's website

We have placed cookies on your device to ensure that we give you the best experience on our website.

This site uses cookies to deliver our services. By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service. Your use of Make School’s Products and Services is subject to these policies and terms.

Please note that Make School no longer supports Internet Explorer

We recommend upgrading to a modern web browser. Learn more