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

Community
  • 1
  • 1
user1460043
  • 2,331
  • 1
  • 19
  • 26
  • Why can't you send json that isn't stringified? Can you give a bit more context? – Josh C. Jun 13 '14 at 02:52
  • @JoshC. Because you can't pass an object from the back-end to the front in a different way. – Etheryte Jun 13 '14 at 02:55
  • 1
    As for the actual question, just escape the necessary characters? – Etheryte Jun 13 '14 at 02: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. – Josh C. Jun 13 '14 at 02:58
  • If this question is "how to get handlebars to use a JSON object for templating", why doesn't res.render() work? – Josh C. Jun 13 '14 at 03:00
  • @JoshC. You might want to take the time and read the question again, the object isn't being passed over a separate request, it's written straight into the HTML. – Etheryte Jun 13 '14 at 03:01
  • @JoshC.— `"json that isn't stringified"`? Like dehydrated water? – RobG Jun 13 '14 at 03:02
  • @RobG I don't follow. Can't you have json, call `JSON.stringify(jsonObj)` and get stringified json? – Josh C. Jun 13 '14 at 03:10
  • @Nit so I've read it again, but I guess I'm not quite getting it. If the javascript is loaded in via script tag and the object is static, then why not load the object in that same resource? Otherwise, the json must be requested. So, why not serve an application/json response via xhr? – Josh C. Jun 13 '14 at 03:12
  • @Nit, escaping the necessary characters - maybe I will have to do this in the end if there is no simpler solution. But it might be tricky to get it right. – user1460043 Jun 13 '14 at 03:30
  • @Josh C., the object is not static. I have to serve text/html anyway and would like to avoid doing a second request to get the object. – user1460043 Jun 13 '14 at 03:54
  • @JoshC.—JSON *is* a string, it's a "stringified" object. :-) – RobG Jun 13 '14 at 06:19

2 Answers2

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.

Brad
  • 159,648
  • 54
  • 349
  • 530
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>
Community
  • 1
  • 1
Plato
  • 10,812
  • 2
  • 41
  • 61
  • I take this approach because it feels cleaner to me to attach data to a relevant dom object than to dynamically generate javascript code – Plato Jun 13 '14 at 05:45
  • 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? – Brad Jun 13 '14 at 16:01