Search code examples
grailsinterceptorgrails-controller

Grails 3 - assign controller's variable in interceptor


I'm upgrading by Grails 2.5.1 web-app to grails 3, but I'm stuck with this problem: in my controllers I was using beforeInterceptors to pre-calculate a set of variables to be used in their action methods.

class MyController {

    def myVar

    def beforeInterceptor = {
        myVar = calculateMyVarFromParams(params)
    }

    def index() {
        /* myVar is already initialized */
    }
}

Now that with Grails 3 interceptors are more powerful and on separate files, how can I achieve the same result? To avoid using request-scope variables, I tried with the following code

class MyInterceptor {

    boolean before() {
        MyController.myVar = calculateMyVarFromParams(params)
        MyController.myVar != null  // also block execution if myVar is still null
    }

    boolean after() { true }

    void afterView() { /* nothing */ }
}

class MyController {

    def myVar

    def index() {
        println('myVar: '+myVar)
    }
}

but I get

ERROR org.grails.web.errors.GrailsExceptionResolver - MissingPropertyException occurred when processing request: [GET] /my/index
No such property: myVar for class: com.usablenet.utest.MyController
Possible solutions: myVar. Stacktrace follows:
groovy.lang.MissingPropertyException: No such property: myVar for class: com.usablenet.utest.MyController
Possible solutions: myVar
at com.usablenet.utest.MyInterceptor.before(MyInterceptor.groovy:15) ~[main/:na]

I assumed (wrongly, apparently) that this would be feasible. Is there a solution? Thanks in advance!

Note: in my case MyController is an abstract class extended by all other controllers


Solution

  • What I was missing is to declare myVar as static, as simple as that!

    Update
    If for any reason you cannot define the variable as static, you can set it as attribute on request object in the interceptor, and read it from there in the controller

    // Interceptor
    request.setAttribute('myVar', calculateMyVarFromParams(params))
    
    // Controller
    request.getAttribute('myVar')