Search code examples
javascriptmysqlnode.jshandlebars.jshandlebarshelper

How to printing JSON objects using handlebar helpers


I have an object that I wanted to print on my html template (handlebars). The value is a count query from mysql server. Here is the function that has query in it:

function getGrade7Applicants(req, res, next) {
connection.query('SELECT COUNT(*) FROM applications WHERE grade="Grade 7" ', function (err, rows, fields) {
    if (err) {
        return next(err);
    };
    req._applications7 = rows;
    return next();
});
}

Here is my GET request on router file:

router.get('/dashboard', getGrade7Applicants, function (req, res, next) {
res.render('admission/dashboard', {
    applications: {
            'grade7': req._applications7
    }

});
});

The handlebar herlper is as below:

Handlebars.registerHelper('toJSON', function(object){
return new Handlebars.SafeString(JSON.stringify(object));
});

And finally my html template is :

<div class="alert alert-success" role="alert">
            <p style="font-size:75px; text-align:center;">{{toJSON applications.grade7}}</p>               
            <p style="text-align:center;"><strong>7th GRADE Applications<strong> </p>
        </div>

After all this, the output on my web page is [{"COUNT(*)":20}]

I don't really know why it prints part of the query. 20 is the right value that I wanted to print.


Solution

  • As mentioned above, that is the property name, here is some further explanation:

    If you have the following query (i gave the count a name of result to make the display more display-friendly:

    SELECT COUNT(*) as result FROM applications WHERE grade="Grade 7"
    

    You should get back a result object that looks something like this:

    [{
       "result": "20"
    }]
    

    So when you stringify it, you get the entire object including the prop name and brackets as text.

    You can pass in the whole array and iterate through it (what you have) in the template, or just the first element then accessing the property by name in the template:

    res.render('admission/dashboard', {
        applications: {
            'grade7': req._applications7[0]
        }
    });
    

    and in the template:

    {{#if applications}}
        {{#if applications.grade7}}
            {{applications.grade7.result}}
        {{/if}}
    {{/if}}
    

    You can also just pass the value directly in the data:

    res.render('admission/dashboard', {
        applications: {
            'grade7': req._applications7[0].result //prop name specified
        }
    });
    

    And in your template:

    {{#if applications}}
        {{#if applications.grade7}}
            {{applications.grade7}}
        {{/if}}
    {{/if}}
    

    You don't need to use the helper unless there is a very specific reason.