No property for controller when sending param to controller from view - grails

I am trying to send a param through a link, but I get the error
No such property: id for class: com.me.MyController
This is the function that I am trying to call in my controller
def myFunction(id){
render(view:'index')
}
And this is the link in my view that I am trying to use to link to the action
<g:link controller="MyController" action="myFunction" params="[id:'1']">My Link</g:link>
Can someone tell me what I am doing wrong?

Your id in the function signature needs a type. For example...
def myFunction(String id){
render(view:'index')
}

Please check out reference to params
and instead try:
def myFunction(){
print params.id
render(view:'index')
}

Related

how to pass one parameter value from admin controller to reports controller in grails

i want to pass caterer value from admin controller to reports controller
getreports.gsp
<g:form url="[admin:catererInstance, action:'save']" >
<div value="${adminInstance.caterer}"></div>
</g:form>
reportscontrooler.groovy
class ReportsController {
def index() {
redirect(action: "_getreports", params: params)
}
def _getreports(){
def adminInstance=new Admin(params)
def adminList=Admin.list().caterer
render(template:"getreports",model:[adminInstance:adminInstance])
}
}
I have modified your code and simply explain how to pass value to controller from your getreports.gsp
getreports.gsp
<g:form url="[admin:catererInstance, action:'save']" >
// Click SEND Button to send value to getreports action
<g:link class="btn btn-info btn-sm" action="getreports" resource="${adminInstance}">SEND</g:link>
</g:form>
reportscontrooler.groovy
// import your admin class here.
class ReportsController {
def index() {
redirect(action: "_getreports", params: params)
}
def _getreports(Admin adminInstance){
// You can get your values Here.
println "adminInstance: "+adminInstance
}
}
You say you have two controllers, but your code shows both of your methods in ReportsController only. If that is the case, you should use forward instead of redirect. If you really meant to issue a redirect to AdminController from ReportsController, then you need to supply controller parameter in your redirect.
Although, this should do the trick, I highly suggest you not to use a redirect here. Better create a new service, maybe ReportsService and move your _getReports() method there. Ideally, services should be handling all your business logic, not controllers.

passing object to from view to object in grails [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Grails populating a domain instance
I am wanting to pass a childInstance object from my view to the controller at the moment I am doing this
<g:formRemote url="[action: 'updateStatus']" update="messages" name="updateStatusForm" onSuccess="document.updateStatusForm.message.value='';">
the updateStatus method is as follows
def updateStatus(String message) {
def status = new Post(message: params.message, author: lookupPerson())
System.out.println("status: " + status.message + " : " + status.author)
status.save(flush: true, failOnError: true)
def messages = currentUserTimeline()
render template: 'profileMessages', collection: messages, var: 'profileMessage'
}
I want to add a childInstance from my view to the updateStatus. But I also want to to work if I don't pass the childInstance to the update Status.
I hope this makes sense.
You cannot pass object instance as request parameter to the controller. Request parameters are strings. So, you can pass something like object ID as a parameter and then load this object by ID in the controller.
Add this to the url
url="[action: 'updateStatus' params:[id:'obj.id']]"
and call it in your controller method with
object = Obj.get(params.id)

Grails controllers pass parameters

My controller is the folowing:
def participated = {
def temp = ConferenceUser.get(params.temp)
def prizes = Prizes.findAllByConferenceUser(temp) // find all rooms where current computer is
def subms = Submissions.findAllByConferenceUser(temp) // find all rooms where current computer is
[temp: temp, priz: prizes, subm: subms]
}
But somehow, when I successfully update a conference value, I wanna go back to the initial page (participated) but I don't know how to pass back the params.temp. (if I do a simple redirect, as the controller is expecting params.temp, it will give me an error because I cannot search prizes with a null object as parameter. So, imagine my update controller is the following:
def update = {
def saveParamshere = params.temp
...
...
(code here)
...
...
redirect(action: "participated", params: [temp: saveParamshere])
}
This code isn't working. How can I successfully go back to my main page and pass in params.temp ?
I think the problem may be, that you are calling update action by submitting form (I suppose). Maybe you are not passing temp value from that form? You can do it by embedding temp as hidden input field into form, or apply it to url by param attribute on form tag.
Using hidden field it might be something like this (in your view file):
<g:form controller="somecontroller" action="update">
(...)
<g:hiddenField name="temp" value="${temp}" />
(...)
</g:form>
Using params attribute:
<g:form controller="somecontroller" action="update" params="[temp : temp]">
(...)
</g:form>
I didn't test any of these so there might be some issues, especially in the second approach.
You could put the params in the flash scope, which lives for two requests, or put them in the session and retrieve them that way.
Here is a link to the grails docs on usage of flash scope:
Grails - Controllers - Controller Scopes

How to attemp sec:loggedInUserInfo into a variable in gsp

I want to get value of sec:loggedInUserInfo and attempt into a variable named user.
My code looks like this:
<sec:loggedInUserInfo field="username" />
<%
def user = *value of field loggedInUserInfo *
%>
Is it possible for doing that?
This is simpler and works fine for me:
<g:set var="user" value="${sec.username()}" />
To assign any field of the UserDetails instance referred to by <sec:loggedInUserInfo> to a variable you can use:
<g:set var="fullName" value="${sec.loggedInUserInfo(field:'fullName')}" />
(see also Custom User Details)
If you want the user object in the gsp, just pass it back as part of the model map from the controller. in a controller action do
def user = springSecurityService.getCurrentUser()
render view: 'yourgsp', model: [user: user]
I am not sure if we can use that tag directly, I couldn't find it earlier, so I have made my custom tag for this purpose
<m:userName id="${session.SPRING_SECURITY_CONTEXT?.authentication?.principal?.id}"/>
def userName = { attrs ->
Long id = attrs['id'] ? attrs['id'].toLong() : null
User user = User?.get(id);
out << user?.firstName
}
I have created one taglib as loggedinUser which is added on gsp page as :
Welcome <g:loggedInUser/> !
Which is showing logged In username on top of each gsp in my project. In custom tag library my code is as follows :
def springSecurityService
def loggedInUser={
if(springSecurityService.getPrincipal().equals("anonymousUser")){
response.sendRedirect("${request.contextPath}/login/auth")
}else{
out <<"${springSecurityService.currentUser.username}"
out << """ [${link(controller:"logout"){"Logout"}}]"""
}
}
So it's showing on each page as : Welcome USERNAME[Logout] !

Grails pattern to reuse template on error

I have a gsp template, where the data for create view is passed through the controller.
def create = {
def bookInstance = new Book()
bookInstance .properties = params
def map = getDefaultValues()
render(template: "create", model: [bookInstance : bookInstance ,
title: map.title,
somelist: somelist
....])
the gsp template
<g:select optionKey="id" from="${somelist}" name="somelist.id" value="${bookInstance ?.somelist?.id}" noSelection="['null': '']"></g:select>
now, in the save method, if there is an error, it returns currently populated and validated instance (default scaffold implementation)
render(template: "create", model: [bookInstance : bookInstance ])
But the fields in the gsp (error page rendered from save action) is empty. I could see the reason as it looks the value in "${somelist}" , but it is not used in save method. Do i just need to check for null in the gsp and use whichever map is available, or any better method (passing all the map in the save method is not an option) ..
thanks in advance..
I figured it out.. I have to pass the same map as was in the create closure .. the reason why we were passing the maps in create is because we wanted to override the default list.. the populated values in bookInstance is only used to preserve the user selection, but not all the values..

Resources