Ok, so this falls in the "Not so sure this is a good idea" department. Stefan Vesterlund posted a comment on my last blog entry concerning returnformat. He asked if it was possible to change the returnFormat at runtime. I said that I didn't think it was possible, but that you could simply use returnFormat="plain" and return JSON or WDDX manually. He played around with it and discovered you could override the default behavior. Consider the following code sample.
<cffunction name="testMethod" access="remote">
<cfset var a = [1,2,4,9]>
<cfreturn a>
</cffunction>
Since I've specified no returnFormat in the cffunction tag, if I hit this via the browser and don't override returnFormat in the query string, the result will be a WDDX string. Now consider this version:
<cffunction name="testMethod" access="remote">
<cfset var a = [1,2,4,9]>
<cfif a[1] is 1>
<cfset url.returnFormat="json">
</cfif>
<cfreturn a>
</cffunction>
The code now checks the first entry in the array, and if the value is 1, it sets url.returnFormat. Surprisingly this works. I guess ColdFusion doesn't bother worrying about the returnFormat settings until the end of the method, which kinda makes sense.
I still feel weird about this one, but thought I'd pass it along.
Archived Comments
I could see this as maybe being useful in the sense that you could have a single multiple use function.
--Dave
Well, my issue is that CF already provides a way to override the returnFormat. The client does it (using the query string). This though is all server side.
I don't know - it just feels wrong. :)
This could be used to make sure the return format isn't altered. (Not that I see a use case issue, but that would be one scenario.)
Would this fail if it was an ajax post instead of a get? ie: url variable would be form variable right?
Possibly. Remember when doing a POST you can still send URL params. But yeah - you can change the code to check form instead (or both).
Personally - when I do Ajax hits, I'll put the returnformat and method in the query string:
some.cfc?method=doit&returnformat=json
and use the Form data for my actual data.
Yes, this is definitely the centerpiece in the "not so sure this is a good idea" department! I've spent the past two hours debugging a "Invalid return type" error. Turns out that using a url.returnFormat="plain" in a CFC function called by another CFC function causes the outer function to be unable to return a valid JSON object...because the returnType for the _entire request_ has been changed to "plain".
In theory, you could do a check to see if url.returnformat is defined, and if not, then set it to plain. That would at least make it like a default and not forcibly change existing requests.