Twitter: raymondcamden


Address: Lafayette, LA, USA

Be careful with returnFormat and JSON

06-03-2008 13,199 views ColdFusion 15 Comments

A user pinged me earlier this morning with an interesting issue. His Ajax application wasn't working as expected. He was using jQuery to hit a CFC. Instead of showing you his code, I simplified it a bit which should make the problem a bit simpler to see. Try and figure it out before reading on:

view plain print about
1<cffunction name="getTime2" access="remote" returnFormat="json">
2    <cfset var s = {}>
3    <cfset s.time = now()>
4    <cfset s.name = "Current Time">
5    <cfreturn serializeJSON(s)>
6</cffunction>

It's a bit subtle - but the issue is that he mixes both returnFormat and serializeJSON. I've blogged about returnFormat quite a bit. It's one of my favorite features of ColdFusion 8 and it got little press. His use of it here though is not something I normally recommend. You can pass returnFormat as an argument in the request or you can specify it in the method inline as he did. To me - using it inline is a bad idea. Not "bad" bad, but I don't think the CFC should be concerned with its return form. Instead, it should simply handle it's business logic and let the caller ask for a particular format.

Where things go wrong is the serializeJSON. What's happening here is that CF first runs the code of the method (Make a struct, then JSON it), and then it formats the result in JSON. So basically it JSON encodes a string that is already JSON encoded.

If you view this result (*), you can see the result is a bit funky:

"{\"TIME\":\"June, 03 2008 08:20:06\",\"NAME\":\"Current Time\"}"

All those \ should tip you off. If you remove the serializeJSON, you see a result that should look a bit better:

{"TIME":"June, 03 2008 08:20:06","NAME":"Current Time"}

I'd remove both the serializeJSON and the returnFormat. I'd then edit the jQuery code's URL to add returnFormat=JSON.

*Ok, so let me use this blog entry to say once again that 99% of Ajax problems can be solved with a tool like Firebug. Firebug would have let you see the Ajax request and response, and if you were familiar with JSON, it would have been an big clue. It's also a handy way to see times when you forget to turn off CF debugging.

15 Comments

  • Commented on 06-03-2008 at 8:35 AM
    Thumbs up for FireBug. I don't think I could even build AJAX applications without it. It simply makes work possible.
  • Commented on 06-03-2008 at 9:10 AM
    Ditto. I find the Javascript cfdebug pretty helpful as well.
  • Commented on 06-06-2008 at 12:21 AM
    Thanks for the article: it's saved us a lot of hassle.

    By the way, please note that "its" is spelled wrongly in the sentence "with it's return form". "it's" means "it is" or "it has", not "of it".
  • Commented on 06-06-2008 at 6:31 AM
    Believe it or not - I have a degree in English. ;) Fixed. I also changed considered to concerned.
  • Commented on 06-06-2008 at 9:55 PM
    I was talking about that with some folks on Tribe recently actually... about how it feels like I'm constantly noticing other people substituting homonyms or just plain not the word they intended when they're writing up blogs or forum posts. Of course, if you noticed yourself doing it at the time, you would correct yourself before it went out, so it's something that only someone else can notice. Although yourself at a later time also qualifies as someone else. :P I was assured that yes indeed, I do it too.
  • Commented on 06-08-2008 at 4:36 AM
    When you dont specify the serializeJSON, how do you tell the function to return the JSON as a column query format. Like this

    returnFormat=json&queryFormat=column

    I use that when I want to "tell the CFC to do it via an URL" but how can I do the same thing directly on the CFC file?

    <cffunction name="foo" returnFormat="json" queryFormat="column">

    Is not good :(
  • Commented on 06-08-2008 at 10:05 AM
    Rual - why would want to? If you want a CFC to always (or by default) return the json, then do it in CFML, use the serializeJSON with the right arg for queryformat. But again though I wouldn't do that. Keep the CFC generic and use the URL params.
  • Commented on 06-08-2008 at 1:28 PM
    Yeah, in fact I have it that way, but I have been playing around with Railo and it appears it doesnt support the URL thing. And when trying to do it via CFML I dont get the same result as CF8

    This is a Spry JSONDataset.
  • Commented on 06-08-2008 at 2:41 PM
    If we didn't have the url thing, then I'd do it in the CFC I guess, but I'd build another method. Ie, one core getFoo() method that returns a native CF query, or whatever, and another method for ajax that wraps getFoo(). That's what I'd do in Railo.
  • Stefan Vesterlund #
    Commented on 07-03-2008 at 6:47 AM
    I was wondering - is there no way to set the returnformat programatically inside the function?

    if (req is JSONP)
    arguments.returnformat='json'
    else
    arguments.returnformat='wddx'

    It feels a bit weird that you can send it as an argument but not treat it as one.
  • Commented on 07-03-2008 at 7:04 AM
    Well, you could obviously do this yourself. Use returnformat=plain and then return wddx or json. To me, I don't view returnFormat as an argument, but more as a operator on the function. (But I haven't had my coffee yet so what do I know?)
  • Stefan Vesterlund #
    Commented on 07-03-2008 at 7:11 AM
    Ahh... I found it, after a bit more trial and error :)

    if (code executed indicates json return)
    url.returnFormat="JSON";
    else
    url.returnFormat="plain";

    That will make my life easier. Sometimes it is simply easier to decide on the server what the returnformat should be, but only after you see the request and it's result. For instance if you have the same methods being accessed by both JSONRPC and JSONP.
  • Commented on 07-03-2008 at 7:16 AM
    Heh, that's cheating. That actually works though? I'll do a test here and blog it later today if so (unless you want to blog it). I don't like it - but it's interesting.
  • Stefan Vesterlund #
    Commented on 07-03-2008 at 7:23 AM
    Cheating on a computer does not really count as a crime :)
    Blog it if you wish, I have no blog. But it works for sure.
  • Commented on 07-03-2008 at 8:24 AM
    Blogged:

    http://www.coldfusionjedi.com/index.cfm/2008/7/3/O...

    Thanks for sharing this Stefan.

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead. Text wrapped in asterisks (*) will be bold and text wrapped in underscores (_) will be italicized.

Leave this field empty