handlebars.jsexpress-handlebars

handlebars #each helper can't iterate correctly


I have a handlebars snippet like below

<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">Name</th>
      <th scope="col">Message</th>
      <th scope="col">Time</th>
    </tr>
  </thead>
  <tbody>
    {{#each result}}
    <tr>
      <th scope="row">{{@index}}</th>
      <td>{{this.name}}</td>
    </tr>
    {{/each}}
  </tbody>
</table>

result is an array from mongodb and present like below

[
  {
    _id: new ObjectId("651de76a44d50f1d9cfedede"),
    name: 'Lucy',
    message: 'I way',
    createdAt: 2023-10-04T22:30:02.377Z,
    updatedAt: 2023-10-04T22:30:02.377Z,
    __v: 0
  },
  {
    _id: new ObjectId("651de7eca2da2627f94ce3cb"),
    name: 'Tanya',
    message: 'I like chemical',
    createdAt: 2023-10-04T22:32:12.465Z,
    updatedAt: 2023-10-04T22:32:12.465Z,
    __v: 0
  },
  {
    _id: new ObjectId("651de8854ee4b125468e6921"),
    name: 'Otto',
    message: 'I from hightower',
    createdAt: 2023-10-04T22:34:45.179Z,
    updatedAt: 2023-10-04T22:34:45.179Z,
    __v: 0
  }
]

if i replace {{this.name}} with {{this}} it'll show

{
    _id: new ObjectId("651de76a44d50f1d9cfedede"),
    name: 'Lucy',
    message: 'I way',
    createdAt: 2023-10-04T22:30:02.377Z,
    updatedAt: 2023-10-04T22:30:02.377Z,
    __v: 0
  }

replace {{this.name}} with {{name}} won't work either (the block will keep blank)


Solution

  • Thanks to @76484's comment and this post

    handlebars API reference

    From version 4.6.0 on, Handlebars forbids accessing prototype properties and methods of the context object by default.

    By changing mongoose query from model.find() to model.find().lean() it works properly.

    This makes queries faster and less memory intensive, but the result documents are plain old JavaScript objects (POJOs), not Mongoose documents. mongoose doc: Faster Mongoose Queries With Lean