Grails 3 JSON render can not render List?

Viewed 1322

I have problem when rendering List result, is grails can not render list? here my code

def findSome(){
    String query = params?.some
    List<Some> someList = Some.createCriteria().list(max : 5) {
        if(query != null && query != ""){
            and {
                like("name", query)
            }
        }

        order("name", "asc")
    }
    someList = someList == null ? new ArrayList<Some>() : someList

    ->> render someList as JSON
}

there is something wrong with my code? what I remember is, grails CAN render List of object. but with this code, always return null in line with mark ->>.

4 Answers

Since the result you obtain from your criteria query is a list of objects, you should use render someList as JSONArray. In order to render as JSON, your list should have corresponding key value pair. You better convert the someList to a map of key-value pairs and render as JSON if you really want JSON object.

   def findSome(){
String query = params?.some
List<Some> someList = Some.createCriteria().list(max : 5) {
    if(query != null && query != ""){
        and {
            like("name", query)
        }
    }

    order("name", "asc")
}
someList = someList == null ? new ArrayList<Some>() : someList

render someList as JSONArray

}

if you want to render as JSON use the following code:

  def findSome(){
def someMap=[:]
String query = params?.some
List<Some> someList = Some.createCriteria().list(max : 5) {
    if(query != null && query != ""){
        and {
            like("name", query)
        }
    }

    order("name", "asc")
}
someList = someList == null ? new ArrayList<Some>() : someList
 someList.each{
   someMap.put(it.id,it) 
 }
 render someMap as JSON

}

You should move the test for query outside of the criteria. No point creating it if query is nothing. You also don't need and in your criteria query, you can just use eq ("name", query)

In you're case the like and eq are the same.

Yes, grails can render object list. About your query, you could simplify to something like this.

def findSome() {
    respond Some.createCriteria().list {
        like 'name', "%$query%"

        maxResults 5
        order 'name', 'asc'
    }
}

If you are concerned that the query parameter is empty you can delegate that responsibility to command objects or url mappings constraints it depends on your case.

In the Responding with JSON section you can find other ways to respond to json

That happened to me only once and I solved it by forcing the response:

render(text: someList as JSON, contentType: 'application/json', encoding: 'UTF-8')

It's quite obvious, but make sure the method is inside a controller and it has this configuration:

static responseFormats = ['json', 'html']
Related