Search code examples
node.jsexpressmongoosehandlebars.js

handlebars.js build in helper #each not working


I am using expressjs and mongoose in backend and handlebars as view engine.

Here is my method in index js

const router = require('express').Router()
const Product = require('../../models/Products')

// Products
router.get('/products',async (req, res) => {
    try{
        const products = await Product.find()
        res.status(200).render('products',{products})
    }catch(err){
        res.status(400).render('products')
    }
})

Documents inside product collection is like this:

[
  {
    _id: new ObjectId("632d74a0b828b58a1d25b047"),
    title: 'Footballs',
    description: 'This is a nice product.',
    images: [
      '/product-images/1663923360491/image1.png',
      '/product-images/1663923360491/image2.png'
    ],
    categories: [ 'football', 'balls', 'sports' ],
    price: 800,
    stock: 300,
    createdAt: 2022-09-23T08:56:00.546Z,
    updatedAt: 2022-09-23T08:56:00.546Z,
    __v: 0
  }
]

And here is the foreach sentence at index.hbs

  <table>
        <thead>
            <tr>
                <td>Date</td>
                <td>Product</td>
                <td>Price</td>
                <td>Options</td>
            </tr>
        </thead>
        <tbody>

            {{#each products}}
            <tr>
                <td>{{this.createdAt}}</td>
                <td>{{this.title}}</td>
                <td>₹{{this.price}}</td>
                <td>
                    <button>edit</button>
                    <button>delete</button>
                </td>
            </tr>
            {{/each}}
            
        </tbody>
    </table>

This code is not working (td tag is empty). But when I put {{@index}},the index of the current array item is displaying but other values are not displaying.

{{#each products}}
            <tr>
                <td>{{@index}}</td>
                <td>{{this.title}}</td>
                <td>₹{{this.price}}</td>
                <td>
                    <button>edit</button>
                    <button>delete</button>
                </td>
            </tr>
{{/each}}

Any help is greatly appreciated, thanks in advance!


Solution

  • If using mongoose, this issue can be solved by using .lean() to get a json object (instead of a mongoose one):

    const products = await Product.find().lean()
    res.status(200).render('products',{products})