Generate JSON With JSON-Views
Asked Answered
C

1

10

I am trying to use JSON-Views in Grails 3.1.

I have the following controller:

package myapp

BasketController {

    def index(ProductFilterCommand cmd) {

        [basketList: service.findAllBaskets()]
    }
}

And the following classes:

package myapp

class Basket {
    List<BasketItem> items
}

class BasketItem  {
    String name 
}

Here are the gson files which I thought would work:

basket/index.gson

import myapp.Basket

model {
    Iterable<Basket> basketList
}

json.baskets(basketList) {
    g.render(template: "basket", model: [basket: it])
}

basket/_basket.gson

import myapp.Basket

model {
    Basket basket
}

json.items(basket.items) { 
    g.render(template: "item", model:[item: it])
}

basket/_item.gson

import myapp.Item

model {
    Item item
}

json g.render(item)

I want to generate json such as:

{
    "baskets": [{
        "items": [{
            "name": "T-shirt"
        }, {
            "name": "Pants"
        }]
    }, {
        "items": [{
            "name": "T-shirt"
        }, {
            "name": "Pants"
        }]
    }]
}

But instead I am getting:

{
  "baskets": [
    {},
    {}
  ]
}
Cundiff answered 8/2, 2016 at 16:10 Comment(3)
Basket, BasketItem - Are they domain classes?Nab
Thanks @Nab It worked perfectly. I've accepted your answer. Sorry for my late answer. they were not domain classes juts plain groovy classes.Cundiff
For POGO unlike domain classes, all these ceremony and templates are not required, just json { baskets basketList } in index.gson would give expected result, hence my question previously. Obviously you would need the model dsl for basketList though. :)Nab
N
10

Looks like a bug to me. The only way to achieve what you are looking for is to use the views as shown below. Also note the usage of collection instead of model. I would file a bug with the sample app I used to test below.

Note the usage of template as a fully qualified name basket/item. This is the defect.

//index.gson
import com.example.Basket

model {
    Iterable<Basket> basketItems
}

json {
    baskets g.render(template: 'basket', collection: basketItems, var: 'basket')
}

//_basket.gson
import com.example.Basket

model {
    Basket basket
}

json {
    items g.render(template: "basket/item", collection: basket.items, var: 'item')
}

//_item.gson
import com.example.BasketItem

model {
    BasketItem item
}

json g.render(item)

//or if id is not required in response
/*json {
    name item.name
}*/
Nab answered 9/2, 2016 at 2:20 Comment(1)
I have this problem with views-1.1.5. The show.gson gets executed and the json output is good. But the index.gson doesnt seem to invoke at all. I had a System.out.println in index.gson to confirm.Roselba

© 2022 - 2025 — McMap. All rights reserved.