Search code examples
javascriptnode.jsexpresshandlebars.jsexpress-handlebars

How to use register helpers for node.js and express handlebars


I have a select option on my form and upon loading a record I want to select the saved option. Here is the code:

Student.hbs file where I am displaying the form, the act obj is coming from student.js route

student.hbs

<form>
    <div class="form-group">
        <label for="day">Day</label>
        <select name="day" id="day" class="form-control">
            <option value="monday" {{{select act.day 'monday'}}}>Monday</option>
            <option value="tuesday" {{{select act.day 'tuesday'}}}>Tuesday</option>
            <option value="wednesday" {{{select act.day 'wednesday'}}}>Wednesday</option>
            <option value="thursday" {{{select act.day 'thursday'}}}>Thursday</option>
            <option value="friday" {{{select act.day 'friday'}}}>Friday</option>
            <option value="saturday" {{{select act.day 'saturday'}}}>Saturday</option>
            <option value="sunday" {{{select act.day 'sunday'}}}>Sunday</option>
        </select>
    </div>
</form>

student.js

router.get('/view/:actUUID', (req, res) => {
    var uuid = req.params.actUUID;
    Student.findByPk(uuid).then(act => {
        res.render('student', {
            act: act 
        });
    });
});

I have created the handlebar helper at /handlers/handlebars.js where I am writing all my helper functions.

app.js

var exphbs = require('express-handlebars');
var hbsHelpers = exphbs.create({
    helpers:require('./handlers/handlebars').helpers, 
    defaultLayout: 'main', 
    extname:'.hbs'
});

app.engine('.hbs', hbsHelpers.engine);
app.set('views', path.join(__dirname, 'views'));                 
app.set('view engine', 'hbs');

/handlers/handlebars.js

function hbsHelpers(hbs) {
    return hbs.create({
        helpers: {
            select: function (selected, option) {
                return (selected == option) ? 'selected="selected"' : '';
            }
        }
    });
}
module.exports = hbsHelpers;

But when I go to the student page I get the following error

Error: Missing helper: "select" at Object. (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/handlebars/dist/cjs/handlebars/helpers/helper-missing.js:19:13) at Object.eval [as main] (eval at createFunctionContext (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:254:23), :15:74) at main (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/handlebars/dist/cjs/handlebars/runtime.js:175:32) at ret (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/handlebars/dist/cjs/handlebars/runtime.js:178:12) at ret (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js:526:21) at ExpressHandlebars._renderTemplate (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/express-handlebars/lib/express-handlebars.js:247:12) at ExpressHandlebars. (/Volumes/Macintosh HD 2/GitHub Cloned Repos/action-tours/node_modules/express-handlebars/lib/express-handlebars.js:173:21)


Solution

  • So it seems there is no need to return hbs.create in the handlebars.js file.

    The correct way to do it will be:

    app.js

    var exphbs = require('express-handlebars’);
    .
    .
    .
    
    var hbs = exphbs.create({
        helpers: require('./handlers/handlebars'),
        defaultLayout: 'main',
        extname:'.hbs'
    });
    
    .
    .
    app.engine('.hbs', hbs.engine);
    

    In the /handlers/handlebars.js

    module.exports = {
        select: function (selected, option) {
            return (selected == option) ? 'selected="selected"' : '';
        }
    };