Search code examples
node.jsexpresshandlebars.jsexpress-handlebars

handlebars, {{#each posts}} disappears the blog page


I am trying to change a blog website to be dynamic. For that, I am using mongoDb and handlebars {{#each ArrayName}} to change it to a dynamic website. When I try to do it with the data which I am taking from my mongoDb, and apply the handlebars code {{#each ArrayName}}, the body code disappears. But if I use static data, it will show in the page. Here is my handlebars code, after the class="row", I used it.

                <div class="row">
                    {{#each Posts}}
                    <div class="col-md-6">
                        <div class="blog">
                            <div class="blog-img">
                                <img src="img/blog2.jpg" class="img-fluid">
                            </div>
                            <div class="blog-content">
                                <ul class="blog-meta">
                                    <li><i class="fas fa-users"></i><span class="writer">John Doe</span></li>
                                    <li><i class="fas fa-clock"></i><span class="writer">{{date}}</span></li>
                                    <li><i class="fas fa-comments"></i><span class="writer">13</span></li>
                                </ul>
                                <h3>{{title}}</h3>
                                <p>{{content}}</p>
                                <a href="blog-single.html">Read More</a>
                            </div>
                        </div>
                    </div>
                    {{/each}}
                </div>

And here is my one sample from sampleData.js

Post.create({
    title: "First post entry.",
    content: "This is the first content of post."
}, 
    (error,post) => {
    console.log(error,post)
})

Here is the Post.js code,

const PostSchema = new mongoose.Schema ({
    title: {type: String, require: true},
    content: {type: String, rqeuire: true},
    date: { type: Date, default: Date.now}
})

And as last, here is my route code,

router.get("/blog" , (req,res) => {
    Post.find({}).then(posts =>{
        res.render("site/blog", {posts:posts})
    })
})

Why would I see the posts in the page when I'm using static data, and why would I not see the posts in the page when I'm using dynamic data?


Solution

  • Update your route to use async/await with Model.find().lean() like so:

    router.get("/blog" , async (req,res) => { //< Note the use of async keyword
       try{
          const posts = await Post.find({}).lean(); //< Note the use await keyword
          res.render("site/blog", {
             posts:posts
          });    
       } catch(err){
          console.log(err);
          //Handle error
       }
    })
    

    When using handlebars {{#each}} helper, you need to use the this keyword to reference the element being iterated over. For example {{this.title}} or {{this.content}} so update your template like so:

    <div class="row">
     {{#each posts}}
        <div class="col-md-6">
           <div class="blog">
              <div class="blog-img">
                 <img src="img/blog2.jpg" class="img-fluid">
              </div>
              <div class="blog-content">
                 <ul class="blog-meta">
                    <li><i class="fas fa-users"></i><span class="writer">John Doe</span></li>
                    <li><i class="fas fa-clock"></i><span class="writer">{{this.date}}</span></li>
                    <li><i class="fas fa-comments"></i><span class="writer">13</span></li>
                 </ul>
                 <h3>{{this.title}}</h3>
                 <p>{{this.content}}</p>
                 <a href="blog-single.html">Read More</a>
              </div>
           </div>
        </div>
     {{/each}}
    </div>
    

    As mentioned in the comments by@76484 please make sure you use posts and not Posts in your handlebars template to loop through the array of posts.