Search code examples
javascriptnode.jsexpress-handlebarsregisterhelper

Getting TypeError as registerHelper is not a function when using handlebars in node js application


My node js application is having the below code wherein I am trying to register a handlebars if-else logic in order to use that in my template file. However it is throwing error as "TypeError: hbs.registerHelper is not a function". Can anybody point me the mistakes I am making and suggest how can I register a if - elseif -else logic to carry out an equality (or comparison) check to construct the decision making logic in my template ?

The express-handlebars version in package.json is 3.0.0

var exp = require('express');
var pth = require('path');
var fcon = require('serve-favicon');
var logger = require('morgan');
var cp = require('cookie-parser');
var bp = require('body-parser');
var exphbs = require('express-handlebars');

var index = require('./routes/index');

var app = express();

exphbs.registerHelper("if", function(conditional, options) {
  if (options.hash.desired === options.hash.type) {
    options.fn(this);
  } else {
    options.inverse(this);
  }
});

// view engine setup
app.engine('hbs', exphbs({extname: 'hbs', defaultLayout: 'layout', layoutsDir: __dirname + '/views/mylayouts/'}));
app.set('views', pth.join(__dirname, 'views'));
app.set('view engine', 'hbs');

Solution

  • Helpers can only be registered for instance of express-handlebars:

    var hbs = exphbs.create({
        // Specify helpers which are only registered on this instance.
        helpers: {
            foo: function () { return 'FOO!'; },
            bar: function () { return 'BAR!'; }
        }
    });
    

    Or if you want to register them dynamic. You can use instance reference like this:

    hbs.handlebars.registerHelper("superHelper", () => 42);
    

    Moving further you may want to override helper at the render level. You can do it like this:

    app.get('/', function (req, res, next) {
        res.render('home', {
            showTitle: true,
    
            // Override `foo` helper only for this rendering.
            helpers: {
                foo: function () { return 'foo.'; }
            }
        });
    });
    

    Source: projects github page

    Edit:

    Adding if helper:

    app.engine('hbs', exphbs({
      extname: 'hbs', 
      defaultLayout: 'layout', 
      layoutsDir: __dirname + '/views/mylayouts/',
      helpers: {
        if: function(conditional, options) {
          if (options.hash.desired === options.hash.type) {
            options.fn(this);
          } else {
            options.inverse(this);
          }
        }
      }
    }));