Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at the New York ColdFusion User Group (Sep. 2009) with:

Maintaining ColdFusion Query Data Type Integrity Throughout The Serialization Life Cycle

By Ben Nadel on
Tags: ColdFusion

Yesterday, I blogged about how JSON (Javascript Object Notation) has become my data format of choice for persisting data to the server in situations where I don't have a database available. This is often the case in "proof of concept" type applications. In the comments to that post, Ray Camden brought up the good point that JSON does create some data type issues since ColdFusion tries to serialize things as stricter data types when using JSON, as opposed to something like WDDX, where ColdFusion seems to err on the side of "string" values.

After Ray, Donnie Bachan brought up the issue of ColdFusion query serialization and deserialization, mentioning that ColdFusion's JSON functions have some extra parameters that afford ColdFusion some latitude when dealing with such specialized objects; specifically, you can ask ColdFusion to automatically convert query-like objects into true ColdFusion queries during the deserialization process.

Both of these points were thought provoking on their own; but together, they are even more interesting. ColdFusion is a typeless language for the most part; but, the one place where data type actually seems to matter (and can cause errors if not taken seriously) is in the query object. Specifically, when one deals with query of queries. Anyone who has performed enough ColdFusion query of queries knows that it's bound to thrown a casting error at some point.

So, when it comes to serializing and deserializing ColdFusion queries, we find ourselves in a situation where data type integrity is both more critical than usual, and, at the same time, much harder to maintain. And, no matter how you serialize a ColdFusion query object, whether it be JSON or WDDX, you lose the original data typing on your query columns. To see this in action, let's manually create an explicitly typed query and then run it through the serialization process:

  • <!---
  • Create a query with explicit data types for columns. Not
  • only does this make you feel all warm and cudly, it also
  • helps prevent unexpected data type issues within CodlFusion
  • query of queries.
  • --->
  • <cfset girls = queryNew(
  • "id, name, dateCreated",
  • "cf_sql_integer, cf_sql_varchar, cf_sql_timestamp"
  • ) />
  •  
  • <!--- Add a few records. --->
  • <cfset queryAddRow( girls, 3 ) />
  •  
  • <!---
  • Set row values. Notice that as we are setting the values, we
  • are using JavaCast() to set the cell value - this is important
  • for query of query integrity (which we all know can be dodgy
  • at times).
  • --->
  • <cfset girls[ "id" ][ 1 ] = javaCast( "int", 1 ) />
  • <cfset girls[ "name" ][ 1 ] = javaCast( "string", "Tricia" ) />
  • <cfset girls[ "dateCreated" ][ 1 ] = now() />
  •  
  • <cfset girls[ "id" ][ 2 ] = javaCast( "int", 2 ) />
  • <cfset girls[ "name" ][ 2 ] = javaCast( "string", "Joanna" ) />
  • <cfset girls[ "dateCreated" ][ 2 ] = now() />
  •  
  • <cfset girls[ "id" ][ 3 ] = javaCast( "int", 3 ) />
  • <cfset girls[ "name" ][ 3 ] = javaCast( "string", "Franzi" ) />
  • <cfset girls[ "dateCreated" ][ 3 ] = now() />
  •  
  •  
  • <!---
  • Now that we have the query, convert the query to WDDX as if
  • we were going to store it on the file system.
  • --->
  • <cfwddx
  • output="wddxData"
  • action="cfml2wddx"
  • input="#girls#"
  • />
  •  
  • <!---
  • Now, rather than storing it in the file system, let's
  • re-create a ColdFusion query object from it.
  • --->
  • <cfwddx
  • output="girlsFromWDDX"
  • action="wddx2cfml"
  • input="#wddxData#"
  • />
  •  
  •  
  • <!--- Output the meta data from the origial query. --->
  • <cfdump
  • var="#getMetaData( girls )#"
  • label="Original Meta Data"
  • />
  •  
  • <!--- Output the meta data from the query we just created. --->
  • <cfdump
  • var="#getMetaData( girlsFromWDDX )#"
  • label="WDDX-Based Meta Data"
  • />

As you can see, we are running our ColdFusion query through WDDX-based serialization and deserialization. We are then outputting the meta data from both the original query and the de serialized query, which will show us the underlying column data types. When we run the above code, we get the following output:

 
 
 
 
 
 
ColdFusion Query Serialization And Deserialization Causes The Loss Of Data Type Integrity. 
 
 
 

As you can see, while the WDDX data was properly converted back into a ColdFusion query object, the data types on the columns were not represented accurately. While this might not seem like a problem at first, as one who's done a lot of work with query of queries, this is very suspicious. So, how do we deal with the loss of data type integrity?

First, I think it's important to make an assumption: when we're dealing with ColdFusion queries in situations where serialization-to-disk is required, most likely, we're dealing with a situation in which our original query objects were manually constructed. After all, if they came out of a database originally, we wouldn't need serialization to persist them. That said, I think it's also fair to assume that if we're deserializing a query object, it's not just to create a new query, but rather, to re-populate an existing query that started off empty.

With that assumption in hand, I tried playing around with a number of different ideas. In the first approach, after we deserialize our WDDX data back into a ColdFusion query object, we can perform a query of queries on that new query object to cast the column data types as necessary. Base on our second assumption - the existence of a manually constructed query with explicit typing - we can use our original query structure as an outline for our query of queries type casting:

  • <!--- Get the meta data of the original query. --->
  • <cfset metaData = getMetaData( girls ) />
  •  
  • <!---
  • Run a query of query, overwriting the "duplicate" query.
  • As we do this, however, we are going to cast the column
  • data types to their originally intended data types.
  • --->
  • <cfquery name="girlsFromWDDX" dbtype="query">
  • SELECT
  •  
  • <!--- Loop over the columns, based on the meta data. --->
  • <cfloop
  • index="columnIndex"
  • from="1"
  • to="#arrayLen( metaData )#"
  • step="1">
  •  
  • <!--- Check for comma requirement. --->
  • <cfif (columnIndex gt 1)>
  • ,
  • </cfif>
  •  
  • <!--- Cast column to original type. --->
  • CAST(
  • #metaData[ columnIndex ].name#
  • AS
  • #metaData[ columnIndex ].typeName#
  • )
  • AS
  • #metaData[ columnIndex ].name#
  •  
  • </cfloop>
  •  
  • FROM
  • girlsFromWDDX
  • </cfquery>
  •  
  • <!--- Output the meta data from the query we just created. --->
  • <cfdump
  • var="#getMetaData( girlsFromWDDX )#"
  • label="WDDX-Based Meta Data (After CAST)"
  • />

Here, after we deserialize our data into the girlsFromWDDX query object, we then overwrite it using a query of queries. Within that query of queries, we use the meta data from our original query object to define our CAST(x AS y) directives. And, when we run the above code and output the new query object, we get the following meta data:

 
 
 
 
 
 
ColdFusion Query Serialization And Deserialization Causes The Loss Of Data Type Integrity. 
 
 
 

As you can see, our new query now has the appropriate data types.

Data type integrity through CAST() is an interesting approach, but it suffers from two major flaws. First, the data types available in CAST() are, very ironically, not the same as the data types available when creating new query columns. When you create columns in a manually created (or altered) ColdFusion query object, you can use any of the following data types:

  • CF_SQL_BIGINT
  • CF_SQL_BIT
  • CF_SQL_CHAR
  • CF_SQL_BLOB
  • CF_SQL_CLOB
  • CF_SQL_DATE
  • CF_SQL_DECIMAL
  • CF_SQL_DOUBLE
  • CF_SQL_FLOAT
  • CF_SQL_IDSTAMP
  • CF_SQL_INTEGER
  • CF_SQL_LONGVARCHAR
  • CF_SQL_MONEY
  • CF_SQL_MONEY4
  • CF_SQL_NUMERIC
  • CF_SQL_REAL
  • CF_SQL_REFCURSOR
  • CF_SQL_SMALLINT
  • CF_SQL_TIME
  • CF_SQL_TIMESTAMP
  • CF_SQL_TINYINT
  • CF_SQL_VARCHAR

However, once inside a query of queries, the CAST() function only recognizes the following, limited set of data types:

  • BINARY
  • BIGINIT
  • BIT
  • DATE
  • DECIMAL
  • DOUBLE
  • INTEGER
  • TIME
  • TIMESTAMP
  • VARCHAR

Granted, the data types that CAST() does not support are not the most commonly used ones; but, if you do have an unsupported data type, the previous method is out of the question. But, even if your data types do not cause an issue, you might still be in trouble. The second serious short-coming of this approach is that it will fail on NULL values. If any of your columns contains a NULL value, the CAST() operation will throw a ColdFusion error.

In the second approach, rather than overwriting our de serialized query object, we use a combination of it and our original query object to manually create a completely new query. This might sound labor intensive, but the QueryNew() and QueryAddColumn() functions makes this extermely easy:

  • <!---
  • Create a query with explicit data types for columns. Not
  • only does this make you feel all warm and cudly, it also
  • helps prevent unexpected data type issues within CodlFusion
  • query of queries.
  • --->
  • <cfset girls = queryNew(
  • "id, name, dateCreated",
  • "cf_sql_integer, cf_sql_varchar, cf_sql_timestamp"
  • ) />
  •  
  • <!--- Add a few records. --->
  • <cfset queryAddRow( girls, 3 ) />
  •  
  • <!---
  • Set row values. Notice that as we are setting the values, we
  • are using JavaCast() to set the cell value - this is important
  • for query of query integrity (which we all know can be dodgy
  • at times).
  •  
  • Notice also that one of our dateCreated times below is being
  • stored as NULL values; using the previous technique (CAST)
  • would have caused a casting error when these NULL values were
  • encoutered in the query of queries.
  • --->
  • <cfset girls[ "id" ][ 1 ] = javaCast( "int", 1 ) />
  • <cfset girls[ "name" ][ 1 ] = javaCast( "string", "Tricia" ) />
  • <cfset girls[ "dateCreated" ][ 1 ] = now() />
  •  
  • <cfset girls[ "id" ][ 2 ] = javaCast( "int", 2 ) />
  • <cfset girls[ "name" ][ 2 ] = javaCast( "string", "Joanna" ) />
  • <cfset girls[ "dateCreated" ][ 2 ] = now() />
  •  
  • <cfset girls[ "id" ][ 3 ] = javaCast( "int", 3 ) />
  • <cfset girls[ "name" ][ 3 ] = javaCast( "string", "Franzi" ) />
  • <cfset girls[ "dateCreated" ][ 3 ] = javaCast( "null", "" ) />
  •  
  •  
  • <!---
  • Now that we have the query, convert the query to WDDX as if
  • we were going to store it on the file system.
  • --->
  • <cfwddx
  • output="wddxData"
  • action="cfml2wddx"
  • input="#girls#"
  • />
  •  
  • <!---
  • Now, rather than storing it in the file system, let's
  • re-create a ColdFusion query object from it.
  • --->
  • <cfwddx
  • output="girlsFromWDDX"
  • action="wddx2cfml"
  • input="#wddxData#"
  • />
  •  
  •  
  • <!---
  • Create a new girls query, but don't add any columns.
  • We're about to add the new columns, one at a time.
  • --->
  • <cfset girlsByColumn = queryNew( "" ) />
  •  
  • <!---
  • Loop over the meta data from the original query and use it
  • PLUS the columns loaded via WDDX to create a new query from
  • scratch with the appropriate data types.
  • --->
  • <cfloop
  • index="local.columnMetaData"
  • array="#getMetaData( girls )#">
  •  
  • <!---
  • Add the column. Notice that as we add the column, we are
  • using the WDDX-column values as our "default" values for
  • the new column. This allows the new data types, but
  • respects NULL column values.
  • --->
  • <cfset queryAddColumn(
  • girlsByColumn,
  • local.columnMetaData.name,
  • local.columnMetaData.typeName,
  • girlsFromWDDX[ local.columnMetaData.name ]
  • ) />
  •  
  • </cfloop>
  •  
  •  
  • <!--- Output the newly created query meta data. --->
  • <cfdump
  • var="#getMetaData( girlsByColumn )#"
  • label="GirlByColumn Meta Data"
  • />
  •  
  • <!--- Output the newly created query. --->
  • <cfdump
  • var="#girlsByColumn#"
  • label="GirlsByColumn Query"
  • />

Here, after we deserialize our WDDX data into a ColdFusion query object, girlFromWDDX, we then create a new and columnless query, girlsByColumn. Then, using the meta data from our original query and the column values from our deserialize query, we add each new column individually to our girlsByColumn query object. In creating the query this way, we keep the data type integrity from our original query while simultaneously using the values from our de serialized data. This is really a best of both worlds approach, which you'll see when we output the new query next to its meta data:

 
 
 
 
 
 
Creating New Queries From Deserialized Data Can Be Used To Create Data-Integrity Query Columns. 
 
 
 

As you can see, the manually created ColdFusion query, girlsByColumn, has both the data types as defined by the original query object as well as the data values represented in the de serialized query. Notice also that the QueryAddColumn() function handled the NULL value without issue. In summary, this approach gives us:

  • Integrity of our original query object data types.
  • Complete support for all data types available to QueryNew().
  • Support for NULL values in our de serialized data.

Up until now, we've only been dealing with WDDX data. The same approach should work for JSON data; and it does, with one large caveat - ColdFusion cannot deserialize the NULL values
in JSON-based queries. Rather than converting a null JSON data point into a null query cell value, ColdFusion turns it into the string literal, "null." To demonstrate, I'm going to perform the exact same process as above, but this time, I'll use JSON as my data format. As you look at following code, take notice that I am using the optional arguments in the serializeJSON() and deserializeJSON() methods to afford ColdFusion some flexibility in the conversion. This is not required, but it makes the algorithm easier:

  • <!---
  • Create a query with explicit data types for columns. Not
  • only does this make you feel all warm and cudly, it also
  • helps prevent unexpected data type issues within CodlFusion
  • query of queries.
  • --->
  • <cfset girls = queryNew(
  • "id, name, dateCreated",
  • "cf_sql_integer, cf_sql_varchar, cf_sql_timestamp"
  • ) />
  •  
  • <!--- Add a few records. --->
  • <cfset queryAddRow( girls, 3 ) />
  •  
  • <!---
  • Set row values. Notice that as we are setting the values, we
  • are using JavaCast() to set the cell value - this is important
  • for query of query integrity (which we all know can be dodgy
  • at times).
  •  
  • Notice also that one of our dateCreated times below is being
  • stored as NULL values.
  • --->
  • <cfset girls[ "id" ][ 1 ] = javaCast( "int", 1 ) />
  • <cfset girls[ "name" ][ 1 ] = javaCast( "string", "Tricia" ) />
  • <cfset girls[ "dateCreated" ][ 1 ] = now() />
  •  
  • <cfset girls[ "id" ][ 2 ] = javaCast( "int", 2 ) />
  • <cfset girls[ "name" ][ 2 ] = javaCast( "string", "Joanna" ) />
  • <cfset girls[ "dateCreated" ][ 2 ] = now() />
  •  
  • <cfset girls[ "id" ][ 3 ] = javaCast( "int", 3 ) />
  • <cfset girls[ "name" ][ 3 ] = javaCast( "string", "Franzi" ) />
  • <cfset girls[ "dateCreated" ][ 3 ] = javaCast( "null", "" ) />
  •  
  •  
  • <!---
  • Now that we have the query, convert the query to JSON; be
  • sure to use the SerializeByQueryColumns flag so that we can
  • more easily deserialize this back into a query. This is not
  • entirely necessary, but makes life easier.
  • --->
  • <cfset jsonData = serializeJSON( girls, true ) />
  •  
  • <!---
  • Now, rather than storing it in the file system, let's
  • re-create a ColdFusion query object from it. Since we
  • serialized the query by column, be sure to deserialize it
  • in the same fashion.
  •  
  • NOTE: This means to not use "strict" mapping - rather let
  • ColdFusion auto-convert the struct to a query.
  • --->
  • <cfset girlsFromJSON = deserializeJSON( jsonData, false ) />
  •  
  •  
  • <!---
  • Create a new girls query, but don't add any columns.
  • We're about to add the new columns, one at a time.
  • --->
  • <cfset girlsByColumn = queryNew( "" ) />
  •  
  • <!---
  • Loop over the meta data from the original query and use it
  • PLUS the columns loaded via JSON to create a new query from
  • scratch with the appropriate data types.
  • --->
  • <cfloop
  • index="local.columnMetaData"
  • array="#getMetaData( girls )#">
  •  
  • <!---
  • Add the column. Notice that as we add the column, we are
  • using the JSON-column values as our "default" values for
  • the new column. This allows the new data types, but
  • respects NULL column values.
  • --->
  • <cfset queryAddColumn(
  • girlsByColumn,
  • local.columnMetaData.name,
  • local.columnMetaData.typeName,
  • girlsFromJSON[ local.columnMetaData.name ]
  • ) />
  •  
  • </cfloop>
  •  
  •  
  • <!--- Output the newly created query meta data. --->
  • <cfdump
  • var="#getMetaData( girlsByColumn )#"
  • label="GirlByColumn Meta Data"
  • />
  •  
  • <!--- Output the newly created query. --->
  • <cfdump
  • var="#girlsByColumn#"
  • label="GirlsByColumn Query"
  • />

This is almost the same as before; the only difference is the data format. And, when we run the code above, here is the query and meta data output that we get:

 
 
 
 
 
 
Using JSON As A Data Format For Query Serialization / Deserialization Can Lead To Issues With NULL Values. 
 
 
 

As you can see, the null query value was de serialized as the string value, "null." This happens anytime that you use JSON as the data format, regardless of whether or not you use the optional serializeJSON() / deserializeJSON() arguments. I assume this happens because queries are pretty much the only place in all of ColdFusion where NULL values don't actually destroy the variable you are trying to evaluate. And, since JSON (hypothetically) deserializes into a struct before it is automagically converted into a ColdFusion query, ColdFusion can't use NULL or it would break the structural integrity of the first step (JSON-to-Struct).

It seems that because ColdFusion query objects are so specialized, anytime you want to serialize and then later deserialize them, you significantly up the complexity of data persistence. However, depending on the constraints of your system, I hope that I have laid out some viable options that allow query serialization and deserialization to take place while maintaining both data type as well as data value integrity.




Reader Comments

Thank you for using my name in your sample code :0) awww that is very sweet of you.

Have a great day!

Reply to this Comment

It's a minor nitpick, but your first assumption is too general -- I've had plenty of cases where I've used WDDX to serialize a query that did come from a database. In the data warehousing apps I've written, it's a real lifesaver. A query might take 90 seconds or 5 minutes to run ... and the built-in caching may not be an option.

But that doesn't invalidate anything -- I'm just being pedantic.

Reply to this Comment

Excellent article! I find it fascinating to be slowly learning more about other languages while also being completely interested...you have a great writing style...er, typing style...? Anyways, good post.

Reply to this Comment

@Rick,

That sounds very cool; data warehousing is definitely not the use case I had in mind - I was thinking more along the lines of no database at all. But, what you're talking about makes perfect sense.

Have you had any problems with the WDDX? How do you generally use the query later? Do you do query of queries? Or do you more just use it as record set to loop over at a later time?

@Kristopher,

Thank you very much; I fear that long posts like this will never get read by any one :) But it's very rewarding to hear that people like yourself are finding value.

Reply to this Comment

This may be OT, but to your code comment about needing JavaCast when setting the query cells - I believe you are incorrect. I've definitely seen QofQ be dodgy before, but _never_ when combined with the second arg to queryNew (the one that lists out the column types).

Reply to this Comment

Out of curiosity have you tried working with Java object serialization? Understand this introduces it's own set of problems, but I think it would be interesting to include in the analysis you've presented thus far, especially how it would interact with query data.

Reply to this Comment

Yeah, DB to WDDX to QoQ mostly. The most common use case is that someone runs a query that takes 2-3 minutes, then we save it so that we can slice and dice it later. But as you said, you definitely have to be wary of data typing issues.

Reply to this Comment

@Raymond,

Hmmm, I am not sure; it is certainly possible my info is out of date. I'll look into this.

@Matthew,

No, I have not tried serializing Java objects.

@Rick,

Ah gotcha. Sounds really cool.

Reply to this Comment

Wow Ben... thanks a million for posting this stuff and following thorough with other posts for guidance.
I banged my head with this stuff many times and was never able to get it to work right.
I have resorted to looping over arrays as hack/fixes to get around this behavior many times, but now I know why. I thought it was something I was doing wrong, but it is all the engine.
You rock man!

Reply to this Comment

Hi Ben

I found this post when I was googling for a related problem and I wondered if you had come across this before.

I take a CF construct (an array of structs containing further arrays of structs, etc.), use cfml2wddx to serialise it, then use wddx2cfml to deserialise it.

This construct gets sent to a WebService using cfinvoke/cfinvokeargument. The WebService has various custom types.

Before I serialise/deserialise the construct I can send it to the WebService and it executes successfully. After I serialise/deserialise, I send the construct and I get back a "could not be found" error, which suggests that the WebService no longer recognises the 'shape' of the construct.

Dumping the before and after versions of the construct to the browser they look identical.

My hunch is that somewhere in the serialise/deserialise process cfwddx is doing something to the data types of the content that the WebService is objecting to, but what, why, and how do I even tell?

[PS. We're using CF7 so I don't have the JSON functions available to me]

Are you able to suggest anything?

Regards,

Reply to this Comment

Aha! Although I am still perplexed by the problem, I do have a workaround/solution.

To anybody else having this problem, and still working on CF7, download the cfjson.cfc from here http://www.epiphantastic.com/cfjson/ and use JSON to serialise/deserialise the construct. It certainly made my problems disappear :-)

As to the original question regarding what cfwddx is doing internally with the data-types, I'd be interested if anyone knows.

Reply to this Comment

@Michael,

Hmm, I have no idea on this matter. That's really weird that it would suddenly become unrecognizable. I'm glad JSON helped to fix the problem. Of course WDDX and JSON are completely different encoding standards, so I assume the only thing that was important was that they were serialized strings (not that one was XML and the other JSON).

Reply to this Comment

I know this is slightly off topic, but it does have to do with data typing during serialization/deserialization.

I am using the bind attribute on a cfselect field. From what I understand, CF automatically performs a serialization and deserialization (into and out of json) for you when using bind. The bind attribute calls a CFC function that returns a query containing two columns, identityid and fullname.

The identityid value is a string that may be alphabetic, numeric or alphanumeric. If it is alphanumeric or alphabetic, everything works fine. However, if it is numeric, with or without leading zeros, it is being converted to a decimal value during the serialization/deserialization that bind does for you.

For example, here is a response the field receives when invoking the call to the cfc:

{"COLUMNS":["ENTITYID","FULLNAME"],"DATA":[["TEST1201","TEST1201"],["TEST1202","TEST1202"],["test1204","test1204"],["test1203","test1203"],[1234.0,1234.0],[123.0,123.0],["T15124","T15124"],["T15712","T15712"],["T34612","T34612"],["T36124","T36124"],[1222.0,1222.0]]}

As you can see, it is return a mixture of numeric and string values. I need to force it to return only strings, so leading 0's are not dropped.

Do you know if this is an issue with bind, cf serialization/deserialization, json, javascript, or something else? Do you know anyway to force the values to always be interpreted as strings?

Reply to this Comment

@Tom,

Yeah, that's a tough spot. I'm still on CF8 in production as well and have seen that issue (not with queries, but with other JSON data). I'd second @Ray's suggestion.

Reply to this Comment

@Ray and @Ben -

Thank you both for your suggestions. I took a look at the page and attempted to implement Gary F's method for manually creating the json response. Unfortunately, cf balks, telling me that "Bind failed for select box patientfind, bind value is not a 2D array or valid serialized query"

I formatted the string to look like the response I pasted above, but it appears that somewhere along the way, CF is escaping each quote. Here is what is being returned

"{\"COLUMNS\":[\"ENTITYID\",\"FULLNAME\"],\"DATA\":[ [\"001222\",\"001222\"]]}"

Do you know how I can force CF to not escape the quotes?

Reply to this Comment

If you bind to a CFC using cfc:, then CF auto adds a returnFormat=json. If your code is doing the JSON serialization itself, then you want to switch from a CFC bind to a URL bind and ensure you pass returnFormat=plain. Ie, CF, don't muck with the response, I've got it covered.

Reply to this Comment

@Tom,

I'm afraid I don't quite get you. If you use returnFormat=json, you have no control over serialization. The only way you have control is if yo uuse returnFormat=plain.

(Technically you can also serialize to XML if you use returnType=xml.)

Reply to this Comment

@Ray -

I meant, but clearly did not very well convey, that according to the CF docs, there seems to be a way to return a manually created json packet from a CFC bind. Unfortunately I can't try right now, but if I set the returnFormat on the cfc function to plain, is that ignored by CF and automatically set to json.

In the CF documentation, it does not explicitly state that the returnFormat needs to be set to plain. But since it appears that it wouldn't work without doing that, I wonder what they meant.

Reply to this Comment

@Tom,

Remember that you can bind to a CFC two ways. Using cfc: syntax and using url: syntax. They both go to the same resource but have different implications.

Using cfc: implies that your CFC is NOT making it's own JSON and is just returning data. CF auto adds a returnformat. You can see this if you use Firebug or another network tool.

Using url: syntax is more low level. You specify the CFC, method, and return format yourself.

As far as I know, it would NOT be possible to roll your own JSON and use CFC: syntax. But honestly, it doesn't matter. Just use url: syntax. You get the same data, same functionality, etc.

Reply to this Comment

@Ray -

I did change to using url: syntax, and returning a manually created json packet, and everything is working great.

Thank you for your sage advice!

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.