Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling render() from a filter helper method in Grails

I have filters like the ones defined below. They run the same code block in various places, so to keep it DRY I refactored that code into a method called doResponse().

class MyFilters {

    def filters = {
        web(uri: '/web/**') {
            before = {

                // Do Stuff
                if (condition) {
                    doResponse(request, response, params)
                }
                return true
            }
            after = {
                if (condition) {
                    doResponse(request, response, params)
                }
                else {
                    // Do Stuff
                    doResponse(request, response, params)
                }

            }
            afterView = {
            }
        }
    }

    boolean doResponse(request, response, params) {
    // Do Stuff
        render(status: statusCode, contentType: "text/xml", encoding: "ISO-8859-1", text: text)
    // Do post-render stuff
        return false
    }
}

However this has a nasty side effect. It seems that the render() method is only available from within the filters closure. Is there any (neat) way for me to call render() from doResponse()?

Edit: The error I get is:

groovy.lang.MissingMethodException: No signature of method: MyFilters.render() is applicable for argument types: (java.util.LinkedHashMap) values: [[status:500, contentType:text/xml, encoding:ISO-8859-1, text:...]]

like image 916
Einar Avatar asked Nov 04 '10 15:11

Einar


1 Answers

Pass the object that defines the render(..) method to the doRespond(..) method, and invoke the render(..) method on that object.

Closures have some implicit variables, including their owner that refers to the parent closure; so we can pass that:

if (condition) {
    doResponse(owner, request, response, params)
}

doRespond(..) method:

boolean doResponse(webFilter, request, response, params) {
    // Do Stuff
    webFilter.render(status: statusCode, contentType: 
        "text/xml", encoding: "ISO-8859-1", text: text)
    // Do post-render stuff
    return false
}
like image 54
robbbert Avatar answered Sep 23 '22 20:09

robbbert