Sumon Bappi
Sumon Bappi

Reputation: 2019

JSON is not working as expected in Grails

I am learning on JSON. I have a view where I am passing a list as JSON on page loading. But in view I am not being able to get the value by key. Here are my attempts below:

My controller action for view:

def jsonObjectCreation(){
    def studentInfo = StudentInfo.getAll()
    def students = new ArrayList<Map>()
    studentInfo.each {
        students.add([
                id: it.id,
                name: it.name,
                address: it.address,
                age: it.age
        ])
    }
    [studentInfo: students as JSON]
}

My jsonObjectCreation view:

    <!DOCTYPE html>
<html>
<title>JSON Object</title>
<body>
<h2>JSON Object Creation in JavaScript</h2>
<p id="demo"></p>
<script>
    var textResult = "";
    var obj = "${studentInfo}";
    alert("${studentInfo}");
    for(var i in obj)
    {
        textResult += obj[i].id + " : " + obj[i].name + "<br>";
    }
    document.getElementById("demo").innerHTML = textResult;
</script>
</body>
</html>

And alert shows this message:

[{&quot;id&quot;:1,&quot;name&quot;:&quot;Sumon&quot;,&quot;address&quot;:&quot;Dhaka&quot;,&quot;age&quot;:18},{&quot;id&quot;:2,&quot;name&quot;:&quot;Bappi&quot;,&quot;address&quot;:&quot;Mirpur&quot;,&quot;age&quot;:17},{&quot;id&quot;:3,&quot;name&quot;:&quot;Saad&quot;,&quot;address&quot;:&quot;Dhaka&quot;,&quot;age&quot;:19}]

And in view id and name is undefined.

Upvotes: 1

Views: 459

Answers (4)

Sandeep Poonia
Sandeep Poonia

Reputation: 2188

By default, Grails plays it safe and escapes all content in ${} expressions in GSPs. All the standard GSP tags are also safe by default, escaping any relevant attribute values.

This is why the the double-quotes (") are escaped as &quot;. To handle this either you can remove html escaping completely by setting it in config.groovy (Bad Idea), or handle it on gsp side.

To handle it on gsp side:

  1. Tell Grails that the content is safe and should be rendered raw: ${raw(studentInfo)}. Using ${raw()} method you can only directly render the content.

  2. Use <g:javascript> tag to write your inline script code. But it will remove any unsafe html code from your content. So if you use <g:javascript>alert("${studentInfo}");</g:javascript> on your gsp page and one of the data corresponding to a key contains <script>alert(123);</script>StName, then this tag will remove the script code part from data. This is really helpful against XSS attacks until and unless you really want to render it.

  3. Manually escape the quotes with in <script/> tag using: var obj = "${raw(studentInfo)}".replace(/&quot;/g, '"'). Although this will not remove any unsafe html but it may break if your any of key or value contains double-quotes ".

After you have stored the data to javascript variable using either 2nd or 3rd approach, now you need to parse the data to a json object. As the javascript variable doesn't know what kind of data it is. So simply do obj = JSON.parse(obj); After this you can iterate over the json object to fetch key and values and continue with your logic.

So using g:javascript code would be:

<g:javascript> var textResult = ""; var obj = JSON.parse("${studentInfo}"); for (var i in obj) { textResult += obj[i].id + " : " + obj[i].name + "<br>"; } document.getElementById("demo_0").innerHTML = textResult; </g:javascript>

Upvotes: 1

Uday
Uday

Reputation: 629

I think you should try

var obj = JSON.parse("${studentInfo}")

Upvotes: 0

Armaiti
Armaiti

Reputation: 766

Try this, instead:

var obj = <%= studentInfo %>;

The above code does not encode the JSON, as "${studentInfo}" does.

Upvotes: 1

Michal_Szulc
Michal_Szulc

Reputation: 4177

Problem wasn't with escaping values but with <script></script> section; instead use:

<g:javascript>
    alert("${studentInfo}");
</g:javascript>

Upvotes: 1

Related Questions