Node.js JSON.stringify() causing " in output. Can't parse with Jquery

80,392

Solution 1

It's because when you call

    res.render('search_tags.jade', { locals: {
        title: 'Search by Tags',
        'pages': pages,
        tagsJSON: JSON.stringify(tagsJSONObj) //pass the tags data as a JSON obj
        }
    });

search_tags.jade is meant to output HTML, so it encodes your quotes. You should use a renderer that doesn't HTML escape, or at least change your view so that your params aren't HTML encoded

If you don't want something in the output escaped, use !{tagsJSON} within the view. However, when outputting JSON, there's no need for a view. you can just take your object, call JSON.stringify. I don't use JADE so I'm not sure if there is a way to create view that can just call JSON.stringify(), but that's what I've done in JSP, velocity, ASP, PHP and Code Igniter (not using JSON.stringify, instead it uses a JSON tool for the given language)

Solution 2

in ejs, its <%- tagsJSON %>

          ^ <---- Note the "-"

Solution 3

Better solution when using Swig.js

{{ data|json|raw }}

Solution 4

Swig Templating Engine method:

Since Swig hasn't been mentioned, I'll add my version in.

I came across this problem today and spent a good few hours trying to get it to work so I could send data to Chart.js: http://www.chartjs.org/docs/

In my case, I was using Geddy.js instead of Express.js. Like the original poster, I also got the html escaped JSON string problem.

I am using Swig templating engine.

Thanks to Juan Mendes for mentioning html escaping, I found this discussion by the developer of Swig:

https://github.com/jnordberg/wintersmith-swig/pull/1

Which led me to search for an option to disable auto escaping.

I first tried:

{{ data|raw }} // didn't work

as it was mentioned in the github page, but that didn't work so I went to documentation and found this:

http://paularmstrong.github.io/swig/docs/tags/

Gold! :D

So final solution:

{% autoescape false %}
var data = {{ data }}
{% endautoescape %}
Share:
80,392

Related videos on Youtube

Jamis Charles
Author by

Jamis Charles

I'm a Full Stack Node.js developer. I work at PayPal (Express, Kraken, React.js, Webpack, Backbone.js)

Updated on July 09, 2022

Comments

  • Jamis Charles
    Jamis Charles almost 2 years

    I am using Node.js (with Express.js) to pass a JSON data object from the server to the client view.

    When I render the JSON object directly to the view I get the JSON object shown on the page as expected (this WORKS):

    pageprovider.findAllTag( function(error, pages){
        res.send(pages);
    })
    

    And my output looks like this (much bigger, many nested obj)

    {"green":{"title":"green","pagesContaining": ""}}
    

    When I try to pass it to my Jade View like this:

    pageprovider.findAllTag( function(error, tagsJSONObj){
            //res.send(pages);
    
        pageprovider.findAll( function(error, pages){
            res.render('search_tags.jade', { locals: {
                title: 'Search by Tags',
                'pages': pages,
                tagsJSON: JSON.stringify(tagsJSONObj) //pass the tags data as a JSON obj
                }
            });
        }) //pageprovider.findAll
    }) //pageprovider.findAllTag
    

    The problem
    When I pass 'tagsJSON' to the view, the output includes the html entities:

    var obj = jQuery.parseJSON( "{&quot;name&quot;: 'value'}");
    

    JQuery throws an error because it doesn't like '"'. How can I get Node to give me the proper quote, or get jQuery to accept this format?

    Any thoughts?

    • Ruan Mendes
      Ruan Mendes almost 12 years
      Are you looking at the output in your browser {"green":{"title":"green","pagesContaining": ""}} ? If you are, then it's been HTML encoded for you. Probably because pageprovider.findAllTag does an HTML encode on what it passes back as the tagsJSONObj parameter. Show the code for pageprovider.findAllTag
    • Ruan Mendes
      Ruan Mendes almost 12 years
      What does search_tags.jade look like?
  • Jamis Charles
    Jamis Charles almost 12 years
    Thank you. !{tagsJSON} worked beautifully. I want to recreate my data set on the client with JS so I can easily manipulate the DOM using that dataset. I didn't want to do an additional Ajax request to fetch that data. That's why I wanted to pass my JSON obj to the JS inside the view. Does that make sense?
  • Ruan Mendes
    Ruan Mendes almost 12 years
    @JamisCharles I see, your view is not displaying only JSON, then !{tagsJSON} is the right way.
  • Kelstar
    Kelstar over 10 years
    This is the correct answer based on the question (which crucially omitted the view code), however, I think it would be better to only pass data/objects to the view, and do the stringify operation there. Try !{JSON.stringify(data)} in your jade template. That's what I settled on.
  • Marcel
    Marcel over 10 years
    Might be obvious but note the - instead of = after <%
  • Ivan Prihhodko
    Ivan Prihhodko about 9 years
    Good approach, if you're using Swig that is.
  • slier
    slier about 9 years
    thank you, i wonder how to parse html tag in swig, now i know by using safe
  • loretoparisi
    loretoparisi almost 6 years
    that's awesome and fixes the issues that the ` | json_encode` does not cover!