• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

CF to output usable JSON

Enthusiast ,
May 28, 2012 May 28, 2012

Copy link to clipboard

Copied

Hi, anyone know a good way to get CF to output JSON from a query in the standard format that JS devs use and not the way CF does it?

TOPICS
Advanced techniques

Views

3.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , May 30, 2012 May 30, 2012

As Adam says, you will have to loop through the data yourself. There are no conversion functions to do it for you. At least, none that I am aware of.

ColdFusion's JSON representation of the query is a struct that has 2 keys, Columns and Data. Columns (always) has one element, an array comprising the column names of the result-set. Data contains an array which itself consists of subarrays. The subarrays represent the respective rows of data. The number of subarrays is therefore arbitrary.

The JS ve

...

Votes

Translate

Translate
LEGEND ,
May 28, 2012 May 28, 2012

Copy link to clipboard

Copied

JSON is JSON: there's not different flavours of it.  What about the JSON is not to your JS chums' liking?

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
May 28, 2012 May 28, 2012

Copy link to clipboard

Copied

Basically CF gives us this:

{"COLUMNS":["SWIFTID","CURRENCY"],"DATA":[["EUR","Euro"],["USD","Dollar"]]}

Basically we need something like this instead that we can easily loop through with JS

{

     {"SWIFTID":"EUR","CURRENCY":Euro},

     {"SWIFTID":"USD","CURRENCY":Dollar}

}

Is there a simple way to get this?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 28, 2012 May 28, 2012

Copy link to clipboard

Copied

Can you not just as easily loop through the DATA array?

If you need to know the column names in your code (for whatever reason), they correspond to the equivalent entry in the COLUMNS array.

Your mooted idea would not work for a recordset, as it's a struct and structs have no sense of ordering, which is intrinsic to a recordset.  Plus why would you want to reproduce the column names EVERY ROW?  They don't change.  That's just bloat.


The short answer is "no: there is no way to 'simply' change the way CF serialises a query into JSON to fit your somewhat idiosyncratic format (which loses important information)".  You'd need to loop over the query and build substructs per row, and stick those into a parent struct.  Then serialise that.  But I really don't think you want to be doing that.

--
Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 30, 2012 May 30, 2012

Copy link to clipboard

Copied

As Adam says, you will have to loop through the data yourself. There are no conversion functions to do it for you. At least, none that I am aware of.

ColdFusion's JSON representation of the query is a struct that has 2 keys, Columns and Data. Columns (always) has one element, an array comprising the column names of the result-set. Data contains an array which itself consists of subarrays. The subarrays represent the respective rows of data. The number of subarrays is therefore arbitrary.

The JS version of JSON you've shown is, in ColdFusion terms, a structure of a structure. You could convert from the ColdFusion version to the JS version as follows:

<cfset testJSON={"COLUMNS":["SWIFTID","CURRENCY","COUNTRY"],"DATA":[["EUR","Euro","EU"],["USD","Dollar","USA"],["GBP","Pound Sterling","UK"],["KRR","Krone","Denmark"],["JPY","Japanese Yen","Japan"]]}>

<cfscript>

function reJSON(json) {

    var newJSON = structnew();

    var i = 1;

    var j = 1;

    /* loop across subarrays that represent rows of data*/

    for(i = 1; i LTE arrayLen(json.data); i=i+1) {

        newJSON = structnew();

        /* Create struct of struct, using each column name as key */

        for(j=1; j LTE arrayLen(json.columns); j=j+1) {

            newJSON[json.columns]=json.data;

        }

    } return newJSON;

}

</cfscript>

<cfdump var="#rejson(testJSON)#">

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
May 30, 2012 May 30, 2012

Copy link to clipboard

Copied

Wow, thanks so much BKBK, thats really cool code sir!

I do get an error though

Invalid CFML construct found on line 1 at column 17.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
May 30, 2012 May 30, 2012

Copy link to clipboard

Copied

and if I pass in this: <cfdump var="#rejson(serializeJSON(rates))#">

I get this:

You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.

im using CF8

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 30, 2012 May 30, 2012

Copy link to clipboard

Copied

Ah, it's just a minor conversion question. My example works because testJSON is already a struct object. When you serialize a query, you get a JSON string. So you first have to convert that string to a struct object. This is done by deserializing.

You can proceed in one of 2 ways. Firstly, assuming the query is rates,

jsonString = serializeJSON(rates);

testJSON = deserializeJSON(jsonString);

Then proceed as above. Secondly, you may redesign the function to accept a string instead. Deserialization should then take place within the function. Something like this:

testJSONString = serializeJSON(rates);

<cfscript>

function reJSON(json_string) {

    var json = deserializejson(json_string);

    var newJSON = structnew();

    var i = 1;

    var j = 1;

    /* loop across subarrays representing rows of data*/

    for(i = 1; i LTE arrayLen(json.data); i=i+1) {

        newJSON = structnew();

        /* Create struct of struct, using each column name as key */

        for(j=1; j LTE arrayLen(json.columns); j=j+1) {

            newJSON[json.columns]=json.data;

        }

    } return newJSON;

}

</cfscript>

<cfdump var="#rejson(testJSONString)#">

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 01, 2012 Jun 01, 2012

Copy link to clipboard

Copied

ah, thanks BKBK, always a helping hand to me

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 01, 2012 Jun 01, 2012

Copy link to clipboard

Copied

the code works now, is there an easy way to remove the row number, ie 56 & 19?

{"56":{"COUNTRY":"Viet Nam","CODE":"VND"},"19":{"COUNTRY":"E  Carib","CODE":"XCD"}}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 01, 2012 Jun 01, 2012

Copy link to clipboard

Copied

LATEST

Nikos, you need to understand that all JSON is is a serialised struct (for all intents and purposes).  There's no magic to any of this.

To answer your question: a struct is a data structure that has key/value pairs, so it needs to have keys (the keys being "56" and "19" in this case).  If you don't want to have keys, then use an array instead.  It'll still have indices, but they're implicit.

TBH, the best approach here would be to simply use the data stucture that CF gives you alredy for a serialised query: it's already in the most sensible structure.  Don't mess around converting it into some other structure based on your JS developers "not getting it".  You should not be doing more work than is necessary based on a developer not knowing how to do something, which is what it sounds like here.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation