Conor Power
Conor Power

Reputation: 726

grails json marshalling

I have a domain object which has a 1 - M relationship with another domain object e.g.

Person 1 -> M Langauges

I have registered a JSON object marshaller to marshall the Person object. A use case I am dealing with is displaying the Person in tabular format where the primary language is displayed by default.

The issue I have is when a user generates a search for language and I want to display the matching language for the person rather than the primary language.

The issue I have is that I do not know how to access the language being searched in the object marshaller and as such I can't determine the matching language to render in the JSON for the tabular format.

Here's the sample code I have for the Person:

JSON.registerObjectMarshaller(Person) {  

 def returnArray = [:]
    returnArray['id'] = it.id
    returnArray['name'] = it.displayName?:""
    //I would like to be able to get the language matching a search param here
    //when a search has been carried out
    returnArray['language'] = it.primaryLanguage?:""

  }

At the moment, the workaround I have is to have a PersonWrapper where I pass the search term in the constructor, register an object marshaller for the wrapper and filter in the wrapper.

This seems pretty wasteful to me as I need to iterate over my domain results and create a wrapper for each instance.

Any suggestions would be gratefully appreciated.

Upvotes: 1

Views: 1374

Answers (3)

AA.
AA.

Reputation: 4606

You can to filter your query and prepare it to render:

import org.hibernate.criterion.CriteriaSpecification

List list = Person.withCriteria {
  maxResults 5
  resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
  alias 'languages', 'lan'
  projections {
    property 'id', 'id'
    property 'displayName', 'name'
    property 'lan.language', 'language'
  }
  eq 'lan.language', 'FR'    
}

then you can to use the result

render list as JSON

You must to use resultTransformer and set alias for each property. Thus you can create custom renders for specific situations.

Note: that code has not be tested, is simply a rough idea.

Upvotes: 0

hitty5
hitty5

Reputation: 1673

maybe you're looking for something like that:

def filterLang = Language.findByCode("de")

// search for persons having the filter language assigned
def foundPersons = Persong.executeQuery("select p from Person as p inner join p.languages as lang where lang = :filterLang",[filterLang : filterLang])

def json = []

foundPersons .each {
    json << [id: it.id, name: it.name, language: filterLang]
}

render json as JSON

Upvotes: 1

hitty5
hitty5

Reputation: 1673

sounds very complicated for such a common use case. you can search through your persons and corresponding languages by using a criteria and than convert the result into a appropriate json format. e.g.

def result = Person.createCriteria().list {
   language {
      eq("lang", "de") // could be your search term
   }
} // you can also use hql to achieve our requirement

def json = []

result.each {
    json << [id: result.id, name: result.name, ...]
}

render json as JSON

Upvotes: 0

Related Questions