Need Handlebars.js to render object data instead of "[Object object]"

JavascriptJsonhandlebars.js

Javascript Problem Overview


I'm using Handlebars templates and JSON data is already represented in [Object object], how do I parse this data outside of the Handlebars? For example, I'm trying to populate a JavaScript variable on the page through a handlebars tag, but this doesn't work.

Any suggestions? Thank you!

EDIT:

To clarify, I'm using ExpressJS w/ Handlebars for templating. In my route, I have this:

var user = {}
user = {'id' : 123, 'name' : 'First Name'}

res.render('index', {user : user});

Then in my index.hbs template, I now have a {{user}} object. I can use {{#each}} to iterate through the object just fine. However, I'm also using Backbonejs and I want to pass this data to a View, such as this:

myView = new myView({user : {{user}});

The problem, is that {{user}} simply shows [Object object] in the source if I put it in console.log I get an error, 'Unexpected Identifier'.

Javascript Solutions


Solution 1 - Javascript

When outputting {{user}}, Handlebars will first retrieve the user's .toString() value. For plain Objects, the default result of this is the "[object Object]" you're seeing.

To get something more useful, you'll either want to display a specific property of the object:

{{user.id}}
{{user.name}}

Or, you can use/define a helper to format the object differently:

Handlebars.registerHelper('json', function(context) {
    return JSON.stringify(context);
});

myView = new myView({
    user : {{{json user}}} // note triple brackets to disable HTML encoding
});

Solution 2 - Javascript

You can simple stringify the JSON:

var user = {}
user = {'id' : 123, 'name' : 'First Name'};
// for print
user.stringify = JSON.stringify(user);

Then in template print by:

{{{user.stringify}}};

Solution 3 - Javascript

I'm using server-side templating in node-js, but this may apply client-side as well. I register Jonathan's json helper in node. In my handler, I add context (such as addressBook) via res.locals. Then I can store the context variable client-side as follows:

<script>
  {{#if addressBook}}
  console.log("addressBook:", {{{json addressBook}}});
  window.addressBook = {{{json addressBook}}};
  {{/if}}
</script>

Note the triple curlies (as pointed out by Jim Liu).

Solution 4 - Javascript

You are trying to pass templating syntax {{ }} inside a JSON object which is not valid.

You may need to do this instead:

myView = new myView({ user : user });

Solution 5 - Javascript

If you want more control over the output formatting you can write your own helper. This one has a recursive function to traverse nested objects.

  Handlebars.registerHelper('objToList', function(context) {
    function toList(obj, indent) {
      var res=""
      for (var k in obj) { 
          if (obj[k] instanceof Object) {
              res=res+k+"\n"+toList(obj[k], ("   " + indent)) ;
          }
          else{
              res=res+indent+k+" : "+obj[k]+"\n";
          }
      }
      return res;
    }    
    return toList(context,"");
  });

We used handlebars for email templates and this proved useful for a user like the following

{
  "user": {
    "id": 123,
    "name": "First Name",
    "account": {
      "bank": "Wells Fargo",
      "sort code": " 123-456"
    }
  }
}

Solution 6 - Javascript

In the Node Router - Stringify the response object. See below line.

 response.render("view", {responseObject:JSON.stringify(object)});

In HTML Script tag - user Template literals (Template strings) and use JSON.parse.

const json= `{{{responseObject}}}`;
const str = JSON.parse(json);

Worked like a charm!

Solution 7 - Javascript

You can render the keys/values of a list or object in a Handlebars template like this:

{{#each the_object}}
  {{@key}}: {{this}}
{{/each}}

Solution 8 - Javascript

To condense (what I found to be) the most helpful answers...

JSON helper for handlebars (credit):

Handlebars.registerHelper("json", function (context) {
    return JSON.stringify(context);
});

JSON helper for express-handlebars (credit and I updated to newest conventions):

app.engine(
    "handlebars",
    exphbs.engine({
        defaultLayout: "main",
        helpers: {
            json: function (context) { 
                return JSON.stringify(context);
            }
        }
    })
);

And then on the templating side: {{json example}}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondzmView Question on Stackoverflow
Solution 1 - JavascriptJonathan LonowskiView Answer on Stackoverflow
Solution 2 - JavascriptnguyênView Answer on Stackoverflow
Solution 3 - JavascriptJeff LoweryView Answer on Stackoverflow
Solution 4 - JavascriptTerryView Answer on Stackoverflow
Solution 5 - JavascriptPhil CView Answer on Stackoverflow
Solution 6 - JavascriptKrishna ChaitanyaView Answer on Stackoverflow
Solution 7 - JavascriptSajjadView Answer on Stackoverflow
Solution 8 - Javascriptcf512View Answer on Stackoverflow