Any way to return a single query row JSONserialized as an object (not an array of one object) keeping numeric valued strings in tack?

66 views
Skip to first unread message

Tim Vanderlois

unread,
Mar 26, 2015, 10:25:01 AM3/26/15
to taffy...@googlegroups.com
Using CF11 - I've been struggling with this for a couple days now... using angularjs $resource save method expects a single object returned from the API (not an array of one object). 

rep(myQuery) works as desired when an array of objects is expected, but in this case an object is expected. I've tried working around by converting the single row query to a struct or array, which then returns a single object; however I'm losing correct serialization with string values that happen to be numeric. "somePropery":12345 should be "someProperty":"12345"

Any thoughts are appreciated.

Adam Tuttle

unread,
Mar 26, 2015, 10:47:28 AM3/26/15
to taffy...@googlegroups.com
Well there are a few things at play, here. First of all, are you aware that Taffy has queryToArray() and queryToStruct() helper methods available in your resources? These will both preserve column name case to whatever you use in your select statement.

return rep( queryToArray( q ) ).withStatus( 200, "OK" );
return rep( queryToStruct( q ) ).withStatus( 200, "OK" );

Secondly, the string -> numeric thing is a bug in ColdFusion's serialization functions. You may find that JSONUtil will do a better job, and there is some information on integrating it with Taffy here.

Lastly, the simplest hack to make it remain a string would be to prepend a non-numeric character that you strip out on the client-side after the response is received.

select concat('@', column) as column from table

This will stop CF from thinking your numeric string should be a numeric value in the data -- but it's a horrible, horrible kludge of a hack that I would only recommend if you're in a big hurry and nobody else will ever be consuming the API (e.g. private, not public).

Good luck! Let us know how you do...

Adam

--
You received this message because you are subscribed to the Google Groups "Taffy Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to taffy-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tim Vanderlois

unread,
Mar 26, 2015, 4:27:42 PM3/26/15
to taffy...@googlegroups.com
Thanks for the reply... your queryToArray() and queryToStruct() are nice functions, but do not maintain data type integrity when serializing, neither did my tools to convert a query to a struct or array.

JSONUtil is also not an option as angularJs does not work well with the serialization of a query format {"COLUMNS":["col1", "col2"], "DATA":[val1, val2],[val1, val2]...} - to get around this using rep()  I'm setting this.serialization.serializequeryas = "struct" in the Application.cfc which produces the nice format of [{ "col1":val1, "col2":val2}, { "col1":val1, "col2":val2}...]

The third option.... well may work, but only as a last resort.

Since you have rep() and noData() - would it be useful to have a noRep(myCustomSerializedData)?

My other option may be to always convert a query to a structure/array before serializing... although I'm not sure that fixes a consistent data type for a column.


--
You received this message because you are subscribed to a topic in the Google Groups "Taffy Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/taffy-users/Wc6gezvv9GY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to taffy-users...@googlegroups.com.

Adam Tuttle

unread,
Mar 26, 2015, 4:51:25 PM3/26/15
to taffy...@googlegroups.com
I think you're confusing two different things here... It's true that JSONUtil doesn't offer the "struct" argument to make a query come out as an array of structures, but if you use JSONUtil *and* queryToArray or queryToStruct, you might find that you get what you're looking for.

Adam

Tim Vanderlois

unread,
Mar 26, 2015, 4:58:18 PM3/26/15
to taffy...@googlegroups.com
I'll give it a try and report the results.

I still think a noRep() method could be useful for custom serializations. 

Tim Vanderlois

unread,
Mar 26, 2015, 5:42:57 PM3/26/15
to taffy...@googlegroups.com
Unfortunately JSONUtil produces the same results - once the query is converted to a structure or array the data type is lost which makes sense as only a query maintains the actual data type.

I did find a solution http://www.bennadel.com/blog/2505-jsonserializer-cfc-a-data-serialization-utility-for-coldfusion.htm ... just need to identify the column names and correlating data type.  A little more configuration, but it works. 

Notably ( not related to this specific thread ) - I did encounter an issue maintaining column name case. Regardless I always get uppercase column names - even when using getmetadata on the query... perhaps its the DB I'm connecting to. Nonetheless - its easy to just always use uppercase.

Thanks for your thoughts.

Adam Tuttle

unread,
Mar 26, 2015, 5:49:44 PM3/26/15
to taffy...@googlegroups.com
Good luck!

Unfortunately I'm not inclined to add a noRep() method to the framework, as manually serializing data is heretical.  ;)

Adam

Irvin Wilson

unread,
Jun 30, 2015, 12:21:16 AM6/30/15
to taffy...@googlegroups.com
This is an old post but if I understand the issue (return numeric as string) I believe you can use JSONUtil and do the following.

change 
                <!--- NUMBER --->
<cfelseif IsNumeric(_data)>
<cfif getClassName(_data) eq "java.lang.String">
<cfreturn  Val(_data).toString()  />
<cfelse>
<cfreturn _data.toString()  />
</cfif>

to

               <!--- NUMBER --->
<cfelseif IsNumeric(_data)>
<cfif getClassName(_data) eq "java.lang.String">
<cfreturn '"' & Val(_data).toString() & '"' />
<cfelse>
<cfreturn '"' & _data.toString() & '"' />
</cfif>

Just above that section there's a section labeled "Strict Mapping" that you can do the same to.  I've only just started doing it this way but so far so food.
Reply all
Reply to author
Forward
0 new messages