1

We are currently working on upgrading our project from Grails 2.2 to Grails 3.0 and have run into numerous issues. The one I'm currently working on has to do with Angular $http() and Command Objects not data binding correctly.

We currently let Grails bind all of our Command objects in our Controller methods. This is done EVERYWHERE and it would be a lot of work to go manually bind everything (Only solution I can come up with right now). We know we need to do this eventually (more control. Grails binds incorrectly constantly) but would rather not unless forced to.

class MyController {
    def updateStatus(StatusCommand cmd) {
        println("params: ${params}")
        println("cmd: ${cmd}")

        // example with objectId = 1 being passed in as http() data
        // params will be: objectId: 1
        // cmd will be: cmd.objectId: null
    }
}

Our previous solution involved an interceptor which would take the request.JSON fields and dump them into params if there was no value already in params.

def beforeInterceptor = {
    if (request.JSON) {
        request.JSON?.each { key, value ->
            if (!params[key]) {
                params[key] = value 
            }
        }
    }
}

With Grails 3.0 Interceptors are now defined outside of the controller separately so I have created the following to replicate what we had before.

class MyInterceptor {
    MyInterceptor {
        matchAll()
    }

    boolean before() {
        if (request.JSON) {
            request.JSON?.each { key, value ->
                if (!params[key]) {
                    params[key] = value 
                }
            }
        }
    }
}

Unfortunately, this doesn't seem to work in Grails 3.0 like it did previously. While the values do seem to be mapped correctly on 'params' the Command Object has everything set to null. I can only assume that the Command Object is now being 'created' before the interceptor has run. Command Objects are correctly bound from our $.ajax() calls since the values are set into params and not request.JSON.

Is there a way to somehow get that created Command Object in the interceptor to set it manually or does anyone have any other ideas for a solution?

EDIT: Example of $http() angular call

var data = { objectId: 1 };
$http({
    method: 'POST',
    url: myUrl,
    data: data
}).success(function() {
    //stuff
});
aclelland
  • 53
  • 5
  • With `$http.post()` and a JSON body, grails command object should automatically get bounded with the payload. Can you also how you call the service from client side (usage of `$http`)? – dmahapatro Mar 23 '16 at 18:54
  • Edited main post with an example call. – aclelland Mar 23 '16 at 19:27
  • Why do you need to add JSON to params manually? Are you sending both URL parameters and JSON body? If yes, there is ongoing topic about it here: https://github.com/grails/grails-core/issues/9707 . – practical programmer Mar 24 '16 at 07:17
  • In this one specific call it is only JSON. However, we do have areas in our application where we send both. The reason we are putting the JSON into params manually is because we only added angular recently so we use params in a lot of our controllers. Because the angular side is working alongside the non-angular side we dumped everything into params to make it simpler in our controllers. Reading through that topic it sounds like it is possible that is what is happening to us, although we don't mix JSON and URL parameters in most of our calls. The majority are either one way or the other. – aclelland Mar 24 '16 at 12:55

0 Answers0