2

I am posting data to a server from the client side using an AJAX call. The data that is sent to the server is in the form of a JavaScript object, that is formed like this:

var dataObj = {
        data: roleList,
        count: count,
        units: unitList
    }

and is posted to the server via a JQuery Ajax call.

The problem is that when the data is received on the server, Grails is adding square brackets to the keys in the data as well as the values. For example, when I print out the "params" on the server, it looks something like this:

[data[]:[data1, data2, data3], count: 3, units[]:[unit1,unit2]]

Whereas it should look like:

[data:[data1,data2,data3]....]

The problem I have with these square brackets is that when I try to use a command object for validation of the data, then the data binding cannot take place as the variable names within the command object do not include the square brackets (and I of course can't create a variable name in Grails to include these brackets)

Does anyone know why these brackets are being added to the keys in the object (when it is the value that is an array and not the key itself) and what I can do to circumvent this problem?

ianh
  • 33
  • 5
  • That is the expected behaviour as documented [here](http://grails.github.io/grails-doc/2.3.6/guide/theWebLayer.html#dataBinding). Data binding should work. What error are you getting? – lvojnovic Jul 27 '15 at 12:19
  • No the data won't bind to the command object because the params of the request have added on the square brackets to the name of the parameter. So instead of having a **data** variable in the params that will map to a **data** variable in the command object, I have a variable called **data[]** that won't bind to the object as there is no corresponding property in the command object called **data[]** What are you saying is the expected behaviour? I looked at the link in your reply but didn't see anything related to my problem. – ianh Jul 27 '15 at 13:47
  • I'm not getting any errors directly from trying to bind the data to the command object, it's just that the command object won't validate and when I check if the data has been bound to the object then I can see that it hasn't...Some of the properties from the params object have been bound however, but just the ones that don't consist of an array of values. Like in the example above, **count: 3** is bound to the command object but the array **data[]:[data1, data2, data3]** isn't bound to the object...because of the brackets on the **data[]** variable name. Do you know what I mean? – ianh Jul 27 '15 at 14:02

1 Answers1

2

This behaviour doesn't come from Grails, but from jQuery, see section about serialization (tradicional vs. not tradicional and how the default was changed) in http://api.jquery.com/jQuery.param/#entry-longdesc

I still find this not very well documented in jQuery, but actually means that array parameters get brackets appended to the parameter name (I'm not sure if there are other consequences). See for example the accepted answer for this:

What is "traditional style of param serialization' in JQuery

You can globablly prevent it by setting the tradicional to true in the ajaxSettings before using jQuery.ajax:

jQuery.ajaxSettings.traditional = true;

For example, in my application.js I have the following at the very beginning:

if (typeof jQuery !== 'undefined') {
   ...
   jQuery.ajaxSettings.traditional = true;
}

Another option is to not send the Javascript object in a form URL encoded way, but as pure JSON inside the body. When doing so, you can access the parsed JSON in the controller by using request.JSON, which works pretty great for data-binding:

Browser's console:

jQuery.ajax({
    type: 'POST', 
    url: 'http://localhost:8080/test/jsonTest', 
    data: JSON.stringify({a: 1, b:2}), 
    async: false,
    contentType: "application/json; charset=utf-8"
}).responseText

Controller:

class TestController {
   def jsonTest() {
      render request.JSON
   }
}
Community
  • 1
  • 1
Deigote
  • 1,721
  • 14
  • 15
  • Ye that was the cause of my problem, thanks for the reply Deigote. – ianh Jul 28 '15 at 10:05
  • Glad to help, I struggled with that myself quite a bit back in the day :-/ . In my case was easy to solve once I found it because I only deal with forms (I serialize and then send them), so I don't have nested Javascript objects. If you are working with Javascript objects and might have nesting, I really recommend the second, JSON-based approach - because the jQuery traditional serialization apparently doesn't handle nested objects very well :-( . – Deigote Jul 28 '15 at 11:24