handlebars.js icon indicating copy to clipboard operation
handlebars.js copied to clipboard

Handlebars does not support class instances in the template data

Open 75lb opened this issue 1 year ago • 1 comments

When rendering a compiled template with an array of custom class instances, this line butchers the input class instance replacing it with a plain object with all custom class behaviour (getters, setters, methods etc) removed. This breaks my app.

Please remove all destructive use of Util.extends() on the input data - leave the input data as it is.

Some pseudocode to illustrate my case. Please let me know if you need anything else.

class Car {
  wheels = []
  maxSpeed
  colour

  constructor (data) {
    this.maxSpeed = data.maxSpeed
    this.colour = data.colour
  }

  hasFourWheels () {}
}

const cars = [
  new Car({ maxSpeed: 40, colour: 'silver' }),
  new Car({ maxSpeed: 30, colour: 'white' })
]

handlebars.registerHelper({
  customHelper: function () {
    /* Fails as the input data is no longer a `Car` instance */
    if (this.hasFourWheels()) {
      // do something
    }
  }
})

/* myTemplate includes use of the `customHelper` helper. */
const compiled = handlebars.compile(myTemplate)
/* throws an error */
compiled(cars)

75lb avatar Sep 08 '24 11:09 75lb

Can confirm this is problem when using class instances as model source and not raw json objects. Will this be fixed or no?

one question:

 context = Utils.extend({}, context, options.hash);

Maybe for better work with class instances, it can use Object.assign

Object.assign(context, options.hash || {});

Here is proof it will help in case of classes: Typescript playground demo

psulek avatar Mar 09 '25 20:03 psulek