Search code examples
javascriptjqueryjsongrailsgsp

pass JSON in GSP page


I'm trying to pass JSON data to GSP page and display table.

Expected JSON:

{
  "data": [
    [
      "Tiger Nixon",
      "System Architect",
      "Edinburgh"
    ]
]}

I'm trying to make it with:

def resp = [data:["System", "One", "Test"]]

[resp: resp]

and display:

<g:javascript>
  $(document).ready(function() {
  $('#example').DataTable( {
     "ajax": "${raw(resp)}"
  } ); } ); 
</g:javascript>

But result in page source code is:

$(document).ready(function() {
    $('#example').DataTable( {
        "ajax": "\u007bdata=\u005bSystem\u002c One\u002c Test\u005d\u007d"
    } );

How to pass it correctly?

UPD1:

When I pass a string it works:

View:

 <g:javascript>
        var str = '${raw(resp)}';
        var json = JSON.parse(str);
        $(document).ready(function() {
        $('#example').DataTable( {
           data: json
        } );
    } );
    </g:javascript>

Controller:

def resp = '[[ \"Tiger Nixon\", \"System Architect\", \"Edinburgh\"]]'    
respond resp, model:[resp: resp]

Page Source code:

<script type="text/javascript">

    var str = '[[ "Tiger Nixon", "System Architect", "Edinburgh"]]';
    var json = JSON.parse(str);
    $(document).ready(function() {
    $('#example').DataTable( {
       data: json
    } );
} );

But when I try to pass

def resp = [["Tiger Nixon", "System Architect", "Edinburgh"]]

it generates an error


Solution

  • Whilst you have got it to work, I think maybe you are manipulating your data into non standard methods to get a result in a round about way.

    I will try and explain an alternative way and a way which can be used within your service to build the map you are sending which then just rendered in controller:

    def resp = [data:["System", "One", "Test"]]

    What you have there is:

    //A groovy map object
    Map resp = [:]
    //It has one element called data which contains a list
    resp.data=[]
    //add in system
    resp.data << 'system'
    resp.data << 'One'
    resp.data << 'Test'
    

    This may have been a list generated by some findBy or other form of db lookup in which case resp.data just becomes the list

    def myList=['system','one','Test']
    resp.data=myList
    

    Now we have back our object as you had it

    def resp = [data:["System", "One", "Test"]]
    or 
    Map resp = [data:["System", "One", "Test"]]
    

    If you now do

    String myResp = (resp as JSON).toString()
    

    You are using groov as JSON to first convert that map to json and finally convert the JSON object into string

    You could have a function in a service that returns either the JSON or finished String object to the controller directly building data dynamically.

    I have only given my two cents because looking at:

    def obj = [["Tiger Nixon", "System Architect", "Edinburgh"]] 
    

    Seems like some odd map you are building just to match your java script which I think could possibly do with improvement to work directly with the given map rather than this strange object:

    <g:javascript>
        var str = '${raw(resp)}';
         var jsonData = JSON.parse(str);
    var jsonResult = jsonData.data;
        $(document).ready(function() {
        $('#example').DataTable( {
           data: jsonResult
        } );
    } );
    </g:javascript>
    

    I think now jsonResult will just hold the object you were looking at. I provided a link to improving javascript to a search result from within one of my plugins. I did some json stuff with that and wschat plugins.

    Haven't tested any of above just going on what how I did it vs your style which looks unusual and possible non comforming to any standards and a harder way to go about building larger dynamic data sets