Search code examples
grailsgrails-controller

Grails: Unable to get model data from controller to view


I have been using Grails for last 3 weeks (learning and working). I have been working on porting a JSP/Servlet application to Grails and it has been absolute "fun" porting the application.

I have facing an issue and have been searching, reading but could not solve it yet.

In the GSP page I have a textfield and search button where user enters ProductID. I have a controller which is called from jQuery Ajax method when a search button is clicked.

 // ----- Part of jQuery Ajax call ---
$.ajax({
        type : "post",
        url : '/${grailsApplication.metadata['app.name']}/product/checkProductAjax',
        data : "pid="+proID,

// ----- Contoller code-----
class ProductController {
      def scaffold = true    
          def checkProductAjax = {
                 def product= Product.findByProductId(params.pid)
                if(product) {
                     [product: product] // model to get data in GSP page.                  
                      render(product.toString() + ":" + product.id)
                } else {
                    render("none")
                }
          }
}

Ajax call and everything works fine. The problem I am facing is how to get the model (i.e. the Product data back to the GSP page i.e. [product: product] and display in GSP as for e.g. Product Name: ${product}

How can I get it working? I have read examples where it is mentioned that just setting the model [product: product] will help to get the data in GSP.

Product Name: ${product} always shows blank in the GSP page Product Name:

Please tell me what I am doing wrong.

Cheers! Jay Chandran


Solution

  • [product: product] and render(product.toString() + ":" + product.id) are incompatible. When you see a controller action whose last line is a map like [product: product] this is the implicit return value since it's the last statement of the action closure - it's the equivalent of return [product: product]. But if you have a map in the middle of a method it's just created and discarded. It's pretty much equivalent to

    def ignoreThisMap = [product: product]
    // other code
    

    Since you're making an Ajax call though, putting the product in the model doesn't make sense since you aren't going to re-render the GSP. You're going to render text, JSON, XML, or some other content that the client-side JavaScript will use to update some subset of the html. So you probably want something closer to

    if (product) {
       render product as JSON
    }
    else {
       render "none"
    }
    

    and then you can use jQuery or Prototype to evaluate the JSON and extract the data in your JavaScript.