1

I have a node/express application and want to pass a javascript object to the browser. Currently I do this by JSON.stringifying the object and printing it into the html:

Node.js/express:

var myObject = /* loaded from db, might look like this: */
               {something: "that has 's and \"s"},
    myObjectString = JSON.stringify(myObject);
...
res.render('my-template', {..., myObjectString: myObjectString});

my-template.handlebars:

<html>
...
<script type="text/javascript">
  var myObjectInBrowser = JSON.parse('{{{myObjectString}}}');
  /* do something to the DOM based on myObjectInBrowser */
</script>
</html>

This leads to problems if myObject contains strings that contain ' or ". This answer to a similar question suggests that I could use replace to manually adjust the stringified object to get everything quoted correctly.

Is there a simpler way to pass a javascript object from node.js to the browser (without doing another request)?

12
  • Why can't you send json that isn't stringified? Can you give a bit more context? Commented Jun 13, 2014 at 2:52
  • @JoshC. Because you can't pass an object from the back-end to the front in a different way. Commented Jun 13, 2014 at 2:55
  • 1
    As for the actual question, just escape the necessary characters? Commented Jun 13, 2014 at 2:56
  • @Nit If node is serving a request, and the response if application/json, it doesn't need to be stringified, right? Also, I'm not sure how this relates to node. Commented Jun 13, 2014 at 2:58
  • If this question is "how to get handlebars to use a JSON object for templating", why doesn't res.render() work? Commented Jun 13, 2014 at 3:00

2 Answers 2

4

In your template, remove the JSON.parse.

var myObjectInBrowser = {{{myObjectString}}};

If you've already encoded the data as JSON, this is directly parseable by the JavaScript engine. If you add another JSON.parse to that, you are double-parsing.

Sign up to request clarification or add additional context in comments.

Comments

0

Quoting my own answer:

I JSON.stringify() any objects that my client scripts need and insert it as HTML5 data-whatever attributes. [then your client script can just read the dom attribute.]

For example:

//app.js
app.get('/map', function(req, res){
  var data = {
    id: '1234',
    LL: {
      lat: 42.1,
      lng: 80.8,
  };
  res.locals.docsJSON = JSON.stringify([data]);
  res.render('locations/index');
});

//jade
!!!
html
  body(data-locations=locals.docsJSON)
  script
    var docs = JSON.parse($('body').attr('data-locations'));
    console.log(docs[0].LL);

//html output
<html> <body data-locations='{"id":"1234","LL":{"lat":42.1,"lng":80.8}}'>
<script> var docs = JSON.parse($('body').attr('data-locations'));  console.log(docs[0].LL); </script>
</body></html>

2 Comments

I take this approach because it feels cleaner to me to attach data to a relevant dom object than to dynamically generate javascript code
It feels cleaner to you to attach data to HTML, then pull it out from the HTML, then parse it, than it is to just parse it in the first place?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.