|
Apologize if this is a duplicate! -- Need help!
Hello all,
I am trying to retrieve an Array of Command Objects returned from my Controller action in the format of JSON in my GSP page. The goal is to display it in a table.
In the controller, I have something like this:
def tabTableList = {//Construct formatted books using a loop formattedBooks << [ id:it.id,name: it.book.name,isbn: it.book.isbn, // publishDate: new java.text.SimpleDateFormat("MMM dd, yyyy").format(book.publishDate),author: it.book.author.name,opfunc: it.selection] def records=[records:[formattedBooks]] records } I played with different ways of returning but they didn't work. Using Render would prompt the user to download the file in the page. If I use converter as follows, the variable ${records} is not recognized at all on the GSP page. //def jsonObj = new JSON(formattedBooks) //def converter = new JSON(records:formattedBooks); //converter.toString() In my view, I am displaying it in a table in the following code: < table> <g:each in="${records}" status = "i" var="record"> <tr class="${(i % 2) == 0 ? 'odd':'even'}"> <td> ${fieldValue(bean:record, field:'name') }</td> <td> ${fieldValue(bean:record, field:'isbn') }</td> <td> ${fieldValue(bean:record, field:'author') }</td> <td> ${fieldValue(bean:record, field:'opfunc') }</td> </tr> </g:each></ table>This code doesn't seem to recgonize the collections. It treats all the items in ${records} as one item and retrieve the names of all the item in the first td. Any suggestions? Thanks, Clara
|
|
If you have a list of books like
def books = Book.list() you can convert with JSON converter return books as JSON
i'm not sure if it's your problem but i hope i can help you Luca 2011/5/18 Clara <[hidden email]> Apologize if this is a duplicate! -- Need help! |
|
Thank you for your reply!
My Controller is created without a domain object. I am using this controller and its associated view to render joined domain objects. The JSON String is as follows: {"records":[[{"id":152,"name":"What I Found in the Tidepool","isbn":"0001-0002-3333-4442","author":"Ducky Duckerson","opfunc":"NoChange"},{"id":188,"name":"Wonderful Williams","isbn":"4672-8893-4678-1112","author":"Alfred Alfredson","opfunc":"NoChange"},{"id":202,"name":"Seven Times Too Many","isbn":"5445-5455-4455-4445","author":"Foster Newman","opfunc":"NoChange"},{"id":227,"name":"1001 Things to do with Chicken Kidneys","isbn":"5112-0047-7657-1009","author":"Chuck Bobuck","opfunc":"NoChange"}]]} This looks like a valid JSON string to me. My question is how I can access this String as a collection from my GSP page. Some posts say that you can retrieve it using a JQuery and I tried window.onload=function handleJsonString(response) { var json = eval('('+response.responseText+')'); var records = document.getElementById("records"); } It didn't seem to work for me. Thanks, |
|
If your goal is to solely use it on gsp's, you can cast it to a map and return as a model part:
def action = { . . . def records = new JSON(yourRecordsList) as Map return [records:records] } This way, records will be a normal parameter available in the gsp action.gsp. Another way, is to keep calling "render yourRecordsList as grails.converters.JSON" and use remotefunction to retrieve it with Ajax. You can then manipulate the incoming content as a JSON object in javascript. I believe it's not what you want, as you're dealing with it in grails tags, which deals better with groovy objects than JSON.
Frederico Galvão - Goiânia GO, Brazil
Fibonacci Soluções Ágeis, PontoGet Inovação Web |
|
Thank you very much for your reply! It is very helpful and I got it working for me with this info. It turned out that I didn't really need to have JSON in this particular section.
Additional info def records = new JSON(yourRecordsList) as Map return [records:records] This doesn't work for me probably because yourRecordsList is a dynamic list. Instead I changed it to a CommandObject Array and return it as model as follows: return records:yourRecordsList The exceptions I got were: Message: No signature of method: grails.converters.JSON.entrySet() is applicable for argument types: () values: [] Possible solutions: every() Caused by: Error processing GroovyPageView: Error executing tag <g:render>: groovy.lang.MissingMethodException: No signature of method: grails.converters.JSON.entrySet() is applicable for argument types: () values: [] Possible solutions: every() at C:/GroovyAndGrails/grailsapps/datatablesample/grails-app/views/newTabTest/tabTableList.gsp:74
|
|
My fault there. It seems I had not get the exact purpose of grails.converters.JSON.
Looking inside it, I can show you a stronger (and working!) example ^^ ".parse" is better if you want to manipulate a string as a map in groovy or gsp cause it returns a JSONElement, but if you plan to only send it from controller to javascript, casting is ok. def stringJson = """{"records":[{"id":152,"name":"What I Found in the Tidepool","isbn":"0001-0002-3333-4442","author":"Ducky Duckerson","opfunc":"NoChange"},{"id":188,"name":"Wonderful Williams","isbn":"4672-8893-4678-1112","author":"Alfred Alfredson","opfunc":"NoChange"},{"id":202,"name":"Seven Times Too Many","isbn":"5445-5455-4455-4445","author":"Foster Newman","opfunc":"NoChange"},{"id":227,"name":"1001 Things to do with Chicken Kidneys","isbn":"5112-0047-7657-1009","author":"Chuck Bobuck","opfunc":"NoChange"}]}""" def jsonExpected = grails.converters.JSON.parse(stringJson) println "JSON parsed from string groupedBy id:\n${(jsonExpected.records.toList().flatten().groupBy{it.id} as Map).entrySet().join('\n')}" assert (jsonExpected.records.toList().flatten().groupBy{it.id.toString()} as Map)['152'].first().author == "Ducky Duckerson" println "A String should be parsed." def map = [:] map['records'] = [[id:"What i found...", isbn: "asdmwkd"], [id:"What i found2...", isbn: "antnbtnrb"], [id:"What i found3...", isbn: "abmktmbt"]] try{ def jsonFail = grails.converters.JSON.parse(map) } catch(MissingMethodException m) { def jsonSuccess = new grails.converters.JSON(map) assert jsonSuccess.target.records.size() == 3 println "A Map can be cast, but cannot be parsed." } The outputs speaks for itself... but any doubts please ask This was run on a 'grails console' @1.3.7, and goes on OK. Your string had an extra array formation ('[]'), not necessary, and could also get you to do a .flatten() on the result in the gsp, as I did in the print above... BTW, the output was as is: JSON parsed from string groupedBy id: 152=[{"id":152,"author":"Ducky Duckerson","isbn":"0001-0002-3333-4442","name":"What I Found in the Tidepool","opfunc":"NoChange"}] 188=[{"id":188,"author":"Alfred Alfredson","isbn":"4672-8893-4678-1112","name":"Wonderful Williams","opfunc":"NoChange"}] 202=[{"id":202,"author":"Foster Newman","isbn":"5445-5455-4455-4445","name":"Seven Times Too Many","opfunc":"NoChange"}] 227=[{"id":227,"author":"Chuck Bobuck","isbn":"5112-0047-7657-1009","name":"1001 Things to do with Chicken Kidneys","opfunc":"NoChange"}] A String should be parsed. A Map can be cast, but cannot be parsed.
Frederico Galvão - Goiânia GO, Brazil
Fibonacci Soluções Ágeis, PontoGet Inovação Web |
|
Hmm.... This is still not working for me. Please see the following exception and stack trace.
It looks like the object parsed from JSON string is an array of objects of map. My GSP page is expecting an array of Objects so that's why I am getting these exceptions? I only started Grails a couple weeks back, not sure how to access an array of map object without searching for it. Thanks for your response. It helps me understand more about JSON and Groovy objects while I am trying your suggestion. Message: Cannot invoke method hasProperty() on null object Caused by: Error processing GroovyPageView: Error executing tag <g:render>: Error evaluating expression [fieldValue(bean:record, field:'name')] on line [5]: Cannot invoke method hasProperty() on null object at C:/GroovyAndGrails/grailsapps/datatablesample/grails-app/views/newTabTest/tabTableList.gsp:64 Class: /WEB-INF/grails-app/views/newTabTest/tabTableList.gsp And the stack trace is: org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error processing GroovyPageView: Error executing tag <g:render>: Error evaluating expression [fieldValue(bean:record, field:'name')] on line [5]: Cannot invoke method hasProperty() on null object at C:/GroovyAndGrails/grailsapps/datatablesample/grails-app/views/newTabTest/tabTableList.gsp:64 at java.lang.Thread.run(Thread.java:595) Caused by: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <g:render>: Error evaluating expression [fieldValue(bean:record, field:'name')] on line [5]: Cannot invoke method hasProperty() on null object at C:/GroovyAndGrails/grailsapps/datatablesample/grails-app/views/newTabTest/tabTableList.gsp:64 at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp$_run_closure2_closure21.doCall(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp:80) at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp$_run_closure2.doCall(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp:66) at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp$_run_closure2.doCall(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp) at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp.run(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest_tabTableList_gsp:89) ... 1 more Caused by: org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error evaluating expression [fieldValue(bean:record, field:'name')] on line [5]: Cannot invoke method hasProperty() on null object at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest__list_gsp$_run_closure2.doCall(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest__list_gsp:23) at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest__list_gsp.run(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest__list_gsp:19) ... 5 more Caused by: java.lang.NullPointerException: Cannot invoke method hasProperty() on null object at C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest__list_gsp$_run_closure2_closure5.doCall(C__GroovyAndGrails_grailsapps_datatablesample_grails_app_views_newTabTest__list_gsp:23) ... 7 more |
|
> Hmm.... This is still not working for me. Please see the following exception
> and stack trace. > It looks like the object parsed from JSON string is an array of objects of > map. My GSP page is expecting an array of Objects so that's why I am getting > these exceptions? > > I only started Grails a couple weeks back, not sure how to access an array > of map object without searching for it. > > Thanks for your response. It helps me understand more about JSON and Groovy > objects while I am trying your suggestion. I think there is a misunderstanding here. GSPs are processed on the server to produce HTML that is then sent back to the browser. It is also common to return JSON, rather than HTML, from the server, in which case the browser processes the JSON. So, it seems that in your case you have no need for JSON at all. All you want to do is pass a list from the controller action to the GSP. The original code you had seemed fine: just return the map return [result: formattedBooks ] If this doesn't work for you, please describe what problems you are encountering. Peter -- Peter Ledbrook Grails Advocate SpringSource - A Division of VMware <http://www.springsource.org/s2gforum2011> --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
Actually, I got both cases working now. I was able to get things working without involving JSON with help from the
first reply. I tried the JSON way only for the sake of understanding more about Grails and JSON...
What I found out is that if the variable is being passed as a map, I need to access it from GSP in the following way: <g:each in="${records}" status = "i" var="record"> <tr class="${(i % 2) == 0 ? 'odd':'even'}"> <td> ${record.name}</td> <td> ${record.isbn}</td> <td> ${record.author}</td> <td> ${record.opfunc}</td> </tr> </g:each> While when I pass the list of Command Objects created from the same content, I need to access it through following code. <g:each in="${records}" status = "i" var="record"> <tr class="${(i % 2) == 0 ? 'odd':'even'}"> <td> ${fieldValue(bean:record, field:'name') }</td> <td> ${fieldValue(bean:record, field:'isbn') }</td> <td> ${fieldValue(bean:record, field:'author') }</td> <td> ${fieldValue(bean:record, field:'opfunc') }</td> </tr> </g:each> Both make perfect sense to me now that I understand a bit more about what JSON is about. Thank you for all your replies! It helps a great deal.
On Fri, May 20, 2011 at 11:00 AM, pledbrook [via Grails] <[hidden email]> wrote:
|
| Powered by Nabble | Edit this page |
