80
votes

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'.

6
You'll have to elaborate on "doesn't work." Can you provide a relevant snippet of code and a description of what you're expecting instead of [Object object]? If you're simply trying to see the object's keys/values, you'll want to use console.log with a debugger or JSON.stringify. - Jonathan Lonowski
Console.log shows [Object object] also. I'll update post to explain better. - dzm

6 Answers

177
votes

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
});
13
votes

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}}};
6
votes

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).

1
votes

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 });

0
votes

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"
    }
  }
}
0
votes

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!