Nothing big, really. However, I did spend part of the morning figuring it out. If you follow me on Twitter, you might've noticed I had to work out a weird problem with ColdBox and jQuery. What was happening was that I had a jQuery plugin working great with CF8, but as soon as I started using it on an app built around ColdBox it stopped working.
The cause of the issues was actually pretty simple. When you create variables in ColdFusion 8 and return them with returnFormat="json", unless you created them in some fancy way the converter will serialize the variable names to upper case. In ColdBox, the opposite happens. Here's an example:
A sample CFC:
2
3 <cffunction name="myService" access="remote" returntype="struct">
4
5 <cfset var result = { myvariable = "test" } />
6
7 <cfreturn result />
8
9 </cffunction>
10
11</cfcomponent>
Nothing too complicated happening here. We simply create a structure and put a single key in it. When outputting the return value in Firebug, here's what you get depending on if you're using CF8's built-in conversion or ColdBox's renderData():
Vanilla ColdFusion 8:
Using ColdBox and renderData():
Considering JS is case-sensitive, this has a pretty big impact on the way we work with returned values. I honestly don't know what I prefer between both solutions, but either way is fine. As long as we can rely on the fact that it's always lower case (or upper case for vanilla CF8), that's good enough for me. Just make sure you start by checking what's in your response.
#1 by Timothy Farrar on 4/23/09 - 2:08 PM
your example was
<cfset var result = { myvariable = "test" } />
so if I did
<cfset var result = { myVariable = "test" } />
would it return
myvariable
or
myVariable
#2 by Francois Levesque on 4/23/09 - 2:24 PM
I'd check just to make sure, but I'm pretty certain that it converts to lower case so you would indeed get myvariable.
#3 by Jason Dean on 4/23/09 - 3:10 PM
#4 by Francois Levesque on 4/23/09 - 3:13 PM
#5 by JY on 4/23/09 - 3:25 PM
#6 by Francois Levesque on 4/23/09 - 3:46 PM
You say that CB matched the case that you used to create your variables. How were you creating them?
<cfset result.myVariable = "test" />
or <cfset result[ "myVariable" ] = "test" />
I believe using the second way ensures the serializer will respect your case, both in ColdBox and CF8. The first option, in my tests, is converted to lowercase or uppercase depending on whether it uses ColdBox's renderData() or not (although serializeJSON() should match whatever CF8 returns when returnFormat is set to "json").
#7 by JY on 4/23/09 - 4:11 PM
I was using the first method you wrote above:
<cfset result.myVariable = value>
<cfset event.renderData("JSON", result>
Then, in firebug, the response showed:
{"myVariable":value}
But then, when I changed to use <cfset event.renderData("plain", serializeJSON(result))>,
I got this {"MYVARIABLE":value} in my response.
#8 by Francois Levesque on 4/23/09 - 4:19 PM
That's odd. I understand the second case, but the first one is leaving me puzzled. I guess it was the way I was declaring my variable:
<cfset result = { myVariable = value } />
I'll need to make more tests to get to the bottom of this. Thank!
#9 by Ben Nadel on 4/23/09 - 5:43 PM
#10 by Francois Levesque on 4/23/09 - 6:58 PM
ColdBox uses a proxy component to receive remote calls and interact with the event handlers. To take advantage of the framework's features you need to pass through this proxy.
In your event handler (the controller), you retrieve the data from your models, arrange it as needed and use the framework's renderData method to let the proxy know what data to return to the calling page.
I haven't tried other frameworks in depth but I'd assume they'd use a similar technique to reap the benefits of being part of a framework.
For more info: http://ortus.svnrepository.com/coldbox/trac.cgi/wi...
Enjoy!
#11 by Ben Nadel on 4/23/09 - 7:01 PM
Hmm, interesting. I have always thought of remote calls themselves as a sort of proxy to the primary framework to begin with; meaning, the remote call might turn around internally and execute a "real" framework request, then return final data normally.
But, like I said, I have no real experience in this :)
I need to check out the ColdBox framework. Everyone raves about it.
#12 by Vaixe on 4/23/09 - 7:09 PM
#13 by Francois Levesque on 4/23/09 - 7:09 PM
I can't really compare it to the other frameworks out there (Model-Glue, Mach-ii, etc), but what caught my attention was the detailed documentation.
There are also plenty of examples and articles written by the community. Jason Dean's series (http://www.12robots.com/index.cfm/ColdBox) comes to mind as a very nice resource :).
#14 by Francois Levesque on 4/23/09 - 7:17 PM
That's an interesting notion. jQuery basically receives a JSON string and parses it to reconstruct the variables locally. I don't know if there's a way to intercept this string and manipulate it first, rather than let jQuery parse it using it's built-in deserializer. Worst case, I imagine it would be possible to write a plug-in that would hook into $.ajaxSetup() to recursively rename keys and variables (not values) to lower / upper case.
Food for thought,
#15 by Luis Majano on 4/23/09 - 9:42 PM
By default the json plugin translates keys to lowercase by default. This is done this way, so the plugin can work on cf7 since the json methods where not introduced until cf8.
How about adding an argument to the renderdata that can control the case of the outputted JSON data. Maybe something like:
//default lower
renderData(type="JSON",data=struct)
//do upper
renderData(type="JSON:UPPER",data=struct);
Anyways, thanks for the pointer, what do you guys think it should do?
#16 by Luis Majano on 4/23/09 - 9:46 PM
Default: lower
renderData(type="JSON", data=struct);
renderData(type="JSON:LOWER", data=struct);
renderData(type="JSON:UPPER", data=struct);
renderData(type="JSON:NOCASE", data=struct);
#17 by Francois Levesque on 4/23/09 - 10:31 PM
That would be really awesome! I can really see a benefit to being able to control whether the serialization converts to lower or upper case. That way we'd know for sure what to expect on the javascript side (and we could reuse JS plugins that were written to work with CF8 and uppercase variable names).
#18 by JY on 4/24/09 - 12:02 AM
Besides struct data, I also notice a case difference for query data. If the query I return is directly from a <cfquery> call, the field names are all in uppercase, but if the query is constructed programmatically using queryNew(fieldNames, types), the field names are in the case entered in the fieldNames list.
#19 by Francois Levesque on 4/24/09 - 12:23 AM
http://blog.critical-web.com/blog/index.cfm/2009/4...