redirect in grails - grails

I am redirecting an uploaded image in grails like so:
Controller:
def upload() {
def f = request.getFile('myFile')
if (f == null | f.empty) {
flash.default = "file cannot be empty"
errors.getFieldError("cannot be empty")
return
}
def fName = f.getOriginalFilename()
def picture = new Picture(orgName: fName, urlOrg: "http://localhost/"+fName)
f.transferTo(new File('/Users/sagarmichael/Desktop/photoUpload/'+fName))
println("saved")
redirect(action: 'test', params: [url1:picture.urlOrg] )
}
def test(){
System.out.println(params.url1)
[url1:params.url1]
}
I would expect this to then send url1 to my view called test where I have this:
<img src="${url1}"/>
I would expect this to then show the image on screen.
I have the apache2 config set correctly and when i go to
http://localhost/<imageName>
it works correctly.
What I am getting is this in the url bar on the browser:
http://localhost:8080/FYP/profile/test?url1=http%3A%2F%2Flocalhost%2Flonglogo3.png
any ideas?

If you use the redirect method with params they will appear in the url. To omit this, you will need to think in another way to design your code.
Looking at your code, it appears that you do the upload of some image and need to show the result. I suggest you pass just the name of the image to your other method and mount the link dynamic (not always will be localhost, wright?). The output url will be:
http://localhost:8080/FYP/profile/test?image=longlogo3.png
If you need to omit the name of the image too you will have to store this in the session.

You are mixing model and URL params. If you really need to have it like this, you have to put the content of param 'url1' into the model in the test() action:
def test() {
return [ 'url1': params.url1 ]
}
I hope, you get the point, I definitely recommend to redesign the code ;-)

Try
render(view:"test", model: [url1:picture.urlOrg])
Or
chain(action: "test", model: [url1:picture.urlOrg])

Related

UrlMappings.groovy default view with parameters

In my UrlMapping.groovy I am trying to reach a specific view of controller sending a param, but this does not work:
"/"(view:'/myController/myAction?myParam=value')
"/"(controller:"myController" action="myAction" params:[myParam:"value"])
"/"(controller:"myController" action="myAction" myParam:"value")
Any idea?
Thanks
"/"(controller:"myController", action:"myAction"){ param="value"}
The answer posted here worked for me:
https://stackoverflow.com/a/28870770/695318
It even works for multiple parameters:
"/some/path"( controller:"admin", action:"whatever") {
myparam = "value"
anotherParam = "Hello World"
}
Access from a controller, e.g. AdminController
def whatever() {
println params.myparam
println params.anotherParam
}
value
Hello World

GRAILS: findALL() vs FindBy---(params.id)

Greeting everyone,
I am trying to pass a parameters from a URL to a findAll() method.
LINE3 I use findAll() to define mouse.
LINE2 def house will bring in the parameter DELAWARE when I go to the page: http://localhost:8080/TestApp/home/county/DELAWARE
House will only show one instance instead of a list.. is there anyway to pass the url instead of ["DELAWARE"]? (please see line 3) thanks :)
def county() {
def house = Home.findByCounty(params.id) //sends only user related address to view
def mouse = Home.findAll("from Home h where h.county= ?", ["DELAWARE"]);
if (!house) {
response.sendError(404)
} else {
[house:house, mouse:mouse ]
}
}
Working Code +1 #Danilo
def county() {
def house = Home.findAllByCounty (params.id) //sends only county specified thru URL e.g. http://localhost:8080/TestAPP/home/county/DELAWARE
if (!house) {
response.sendError(404)
} else {
[house:house ]
}
}
findBy* will return at most one row, if you want to get all rows use findAllBy*
In order to understand how the URL will be used by Grails you have to have a look at conf/UrlMappings.groovy. You may find something like this:
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
}
}
this means that when you call TestApp/home/county/DELAWARE what Grails is trying to do is use the home controller (HomeController), invoking the county method (def county(){...}) and passing DELAWARE as id.
This should work correctly if inside county method of the HomeController you have:
def filteredInstances = Home.findAllByCounty(params.id)

Grails parameter passing

Basically I am using the code below for debugging. It renders null and I cannot figure out the
reason. And by the way the else statement will always be executed at this point. At first I
didnt have the save method but I then thought it might fix my issue. May is have to do with
the scope of my domains? As of now I have them set to session scope:
class Info {
static scope = "session"
String name
String smokingStatus
String[] symptom
static constraints = {
}
}
else{//query did not find patient with that id
def patInfo = new Info()
patInfo.name = "Dennis"
patInfo.smokingStatus = "Former Smoker"
patInfo.symptom = ["Cough"]
patInfo.save()
redirect(action:"display", params: [patInfo:patInfo])
//redirect(action:"login")
//return to login action and
}
}
}
def display(){
render params.name
}
Thanks for any help its much appreciated.
You are assign the value of patInfo to variable name patInfo so in the display action you must use:
render params.patInfo
By example if you will use the following:
redirect(action:"display", params: [duck:patInfo])
You must use:
render params.duck

Grails render changes url to index

I've got this method on my controller, which basically validates and saves entity or renders errors if any:
def initCreateProduct() {
render view: "/admin/product/createProduct"
}
def createProduct(params) {
def product = new Product(params)
if (product.validate()) {
flash.message = "product.createSuccess"
product.save(failOnError: true);
redirect action: "initCreateProduct"
} else {
render view: "/admin/product/createProduct", model: [product: product]
}
}
It works fine in case if validation is successfull (URL in browser is "product/initCreateProduct", which is ok), but in case if validation fails my URL changes to "product/index", which is wrong. What I need is to get the same URL in both cases (it's the same page after all). Thanks in advance.
Update: finally solved it.
The problem is caused by used in my gsp, which basically changes action url to index, and sends real action as post-method parameter. To save action in url I have used instead of
It is doing a controller redirect and not being able to resolve an URL. IIRC, grails will pass additional parameters to the index method to find that action.
If you do something like this, it won't do it:
if (product.validate()) {
flash.message = "product.createSuccess"
product.save(failOnError: true)
initCreateProduct()
}

Detect redirect in Grails

At the end of my save action I redirect to the show action like this:
redirect(action: "show", id: exampleInstance.id)
In my show action I want to be able to detect if someone came directly to this action via a url, or if they were redirected here from another action. I tried request.isRedirected() but it always returns false.
How do I detect if I am in an action as the result of a redirect from another action?
I guess you want to display a confirmation message. Grails has a built-in feature for this kind of use-case:
http://www.grails.org/doc/2.1.0/ref/Controllers/flash.html
Have a look at the example:
class BookController {
def save() {
flash.message = "Welcome!"
redirect(action: 'home')
}
}
In the view you can print or check against flash.message.
In theory, isRedirect checks request attributes. It is equivalent to
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes
if(request.getAttribute(GrailsApplicationAttributes.REDIRECT_ISSUED) != null){
println "request was redirect"
}
Try it directly and tell me what happens.
It looks like in the Grails source that isRedirected() is only applicable to the save action, as it gets set in the redirect() method logic, and so wouldn't be set in the show action.
Instead, here are some manual options. One is to add a flag to the flash object, which is then tested in the redirect action. Since it is in flash scope it will be cleared at the end of the show action:
def save() {
// Do stuff
flash.redirectFrom = "save"
redirect(action:"show")
}
def show() {
if (flash.redirectFrom) {
// Respond to redirect
}
// Do other stuff
}
Another option is to issue a chain() call instead of a redirect() and test for the implicit chainModel object. The chainModel won't exist when the show action is requested from an external URL:
def save() {
// Do stuff
chain(action:"show",model:[from:'show'])
}
def show() {
if (chainModel) {
// Respond to redirect
}
// Do other stuff
}

Resources