Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering JSON in grails

Tags:

json

grails

I use the following code to render data in JSON format.

render(contentType:"text/json") {
    results = array {
        db.eachRow(query) { row ->
            def rs = row.toRowResult()
            def a = b(rs.name,c,d)
            aMap.put("A",a) 
            pair(aMap)
        }
    }
    if (results) {
        status = "OK"
    }
    else {
        status ="Nothing present"
    }
}

The above code generates JSON in the following format

{
    "results": [
        {"A":"value1"},
        {"A":"value2"},
        ...................
        {"A":"valuen"}
    ],
    "status":"OK"
}

As u see above, the data is rendered as an array of objects. Is there a way I can render the results data as an array of elements. Like

{
    "results": [
        "value1",
        "value2",
        ...................
        "valuen"
    ],
   "status":"OK"
}
like image 989
Shenoy Tinny Avatar asked Mar 09 '12 19:03

Shenoy Tinny


3 Answers

Only off by a little bit :) Just need to change

aMap.put("A", a)

to be a collection or list, rather than a map. so something like

def aList = []
aList << a

Will get you what you want!

As a sidenote, there is a JSON converter in grails that will do that string building for you. Look into it here

like image 43
Will Buck Avatar answered Nov 02 '22 09:11

Will Buck


The way the JSON object is being built is quite obscure. What I like doing to render JSON responses in grails is creating a map or list in groovy and then use the render method just to convert it to JSON.

Doing the transformation of the rowResult's inside the render method makes it quite confusing, I'd rather go for something like this

def results = db.rows(query).collect { rowResult ->
    b(rowResult.name, c, d) 
}
render(contentType: 'text/json') {[
    'results': results,
    'status': results ? "OK" : "Nothing present"
]}

I think it's more readable, and even shorter. This snippet gets you the desired result: no objects inside the results array, just strings.

Note the use of rows, which returns a list of RowResult's, eliminating the need to get it from the ResultSet's. The list is used to collect the transformed value a by calling b on each row's name. Collecting the elements doesn't imply creating a map (like in the { "A":"value1"} JSON you were getting), just the same @will-buck achieved with the << operator on a new, empty list.

All we do with the render method is declaring the text/json content type and passing it a literal map containing the keys results and status, which you want to write to the response. The conditional operator is used to concisely determine the status. It could also be used like this, by means of the JSON converter @will-buck also mentioned:

def responseData = [
    'results': results,
    'status': results ? "OK" : "Nothing present"
]
render responseData as JSON
like image 150
Esteban Avatar answered Nov 02 '22 08:11

Esteban


This should be enough to render a JSON from controller:

render results as grails.converters.JSON
like image 2
IgniteCoders Avatar answered Nov 02 '22 07:11

IgniteCoders