How to dynamically create complex JSON with Grails 1.2?

I would like to make a complex type using the JSON rendering method in Grails, similar to the JSON output below:

{"authors":[{"id":1,"name":"Author 1","books":[{"id":1,"name":"Book 1"},{"id":2,"name":"Book 2"}]},{"id":2,"name":"Author 2","books":[{"id":1,"name":"Book 1"},{"id":2,"name":"Book 2"}]}]}

And I tried to do this with the following code, where Author and Book are domain classes containing property identifiers and name and where Author hasMany Books (association).

def results = Authors.list()
render(contentType:"text/json") {
  authors = array {
    for(a in results) {
      author id:a.id, name:a.name, books: array = {
        def bookresults = Book.findAllByAuthor(a)
        for(b in bookresults) {
          book id:b.id, name:b.name
        }
      }
    }
  }    
}

It works great with authors alone, but not when I try to iterate through each authors book and render them, the code does not work.

Any ideas?

Updated final code question

Thanks to Dave's answer, I got the following code that works as expected:

def authors = []

for (a in Author.list()) {
  def books = []
  def author = [id:a.id, name:a.name, books:books]

  for (b in Book.findAllByAuthor(a)) {
    def book = [id:b.id, name:b.name]
    books << book
  }

  authors << author
}

def items = [authors:[authors]]
render items as JSON 
+3
source share
1 answer

, JSON- , ​​, .

- (: !):

def results = []
Authors.list()?.each{ author ->
    def authorResult = [id:author.id, name:author.name]
    Book.findAllByAuthor(author)?.each { book ->
        authorResultput('books', [id:book.id, name:book.name])
    }
    results << authorResult
}
def authors = [authors: results]
render authors as JSON

, , , ( ).

JSON, JSON- Bootstrap.groovy. - :

    JSON.registerObjectMarshaller(Author) {
        def returnArray = [:]
        returnArray['id'] = it.id
        returnArray['name'] = it.name
        return returnArray
    }

, !

+10

Source: https://habr.com/ru/post/1732735/


All Articles