2

I have version of the code that works fine in ColdFusion 10 but ColdFusion 9 I'm getting this error:

SyntaxError: JSON.parse: expected ',' or '}' after property value in object at line 1 column 13714 of the JSON data

Here is my cffunction where my data is converted to JSON:

      <cffunction name="getBuildings" access="remote" output="true" returnformat="JSON">
                <cfset fnResults = structNew()>

                <cfquery name="getBldg" datasource="myData">
                    SELECT
                        LTRIM(RTRIM(number)) AS bldgNum, 
                        LTRIM(RTRIM(name)) AS bldgName
                    FROM Bldg WITH (NOLOCK)
                    ORDER BY name
                </cfquery>

                <cfset fnResults.recordcount = getBldg.recordcount>

                <cfif getBldg.recordcount EQ 0>
                    <cfset fnResults.message = "No Buildings found.">
                <cfelse>
                    <cfloop query="getBldg">
                        <cfset fnRecBldg[currentRow] = StructNew()>
                        <cfset fnRecBldg[currentRow].bldgName = URLEncodedFormat(getBldg.name)>
                        <cfset fnRecBldg[currentRow].bldgNumber = getBldg.number>
                    </cfloop>
                    <cfset fnResults.data = fnRecBldg>
                </cfif>

                <cfset fnResults.status = "200">
          <cfreturn fnResults>
     </cffunction>

Here is my JQUERY:

function getBldg(){
    var dist = $('.chBldg');

        $.ajax({
            type: 'POST',
            url: 'Application.cfc?method=getBuildings',
            data: {},
            dataType: 'json'
        }).done(function(obj){
            var numRecs = obj.RECORDCOUNT;

            if(obj.STATUS == 200){
                if(numRecs == 0){
                    dist.find("option:gt(0)").remove();
                }else{
                    dist.find("option:gt(0)").remove();

                    for(var i=0; i < numRecs; i++){
                        var jsRec = obj.DATA[i];
                        dist.append($("<option />").val(jsRec.BLDGNUMBER).text(decodeURIComponent(jsRec.BLDGNAME) +' ('+ jsRec.BLDGNUMBER +')'));
                    }
                }
            }else{
            }
        }).fail(function(jqXHR, textStatus, errorThrown){
            alert(errorThrown);
        });
    }
}

Here is small example of rerurned data:

{"RECORDCOUNT":4,"STATUS":200,"DATA":[
    {"BLDGNAME":"Fall%2DCasey","BLDGNUMBER":"0012"},
    {"BLDGNAME":"Autmun","BLDGNUMBER":"0022"},
    {"BLDGNAME":"Cedar","BLDGNUMBER":0201},
    {"BLDGNAME":"Great%20Lake","BLDGNUMBER":1215}]}

This error must be related to ColdFusion version 9/10 and the way my JSON data is organized. I still didn't find the bug. If anyone see where my code id breaking please let me know.

espresso_coffee
  • 5,980
  • 11
  • 83
  • 193
  • I work on a smaller sample of data and then keep adding more and more until I found what triggered the error. But if I had to guess, I would bet that it is an un-escaped character. Last but not least I would load CF 2016 onto a dev box and run the code there. – James A Mohler Oct 26 '17 at 17:35
  • Look at the data around character position 13714 mentioned in the error. That will probably give you a clue. – Miguel-F Oct 26 '17 at 18:01
  • @Miguel-F I found character on position 13714. Here is the value: BLDGNUMBER:0000 I'm not sure why I'm getting an error. – espresso_coffee Oct 26 '17 at 18:20
  • JSON does not allow number to be starting with 0. If yoi want number starting with 0 in your JSON you have to wrap it in quotes and so that it will be treated as string and JSON parser won't throw an error. In your case have a number 0201 which is not wrapped in quotes. Hence it's towing an error. For more details see https://stackoverflow.com/questions/27361565/why-is-json-invalid-if-an-integer-begins-with-0. And to check your JSON return is valid or not https://jsonlint.com – Keshav jha Oct 26 '17 at 18:22
  • @Keshavjha can you please provide any example on how to wrap the numeric values in the quotes. I have tried something like this '#number#' but still is throwing an error. – espresso_coffee Oct 26 '17 at 18:32
  • @espresso_cofee wrap it in double qotes like "#number#" and it should work. – Keshav jha Oct 26 '17 at 18:36
  • @Keshavjha I tried that too and still throws an error. Also if you see my JSON data example above you see that all numeric values have double quotes around. – espresso_coffee Oct 26 '17 at 18:38
  • Except this one {"BLDGNAME":"Cedar","BLDGNUMBER":0201} – Keshav jha Oct 26 '17 at 18:39
  • @Keshavjha I'm confused why some numbers are in the quotes and some are not.... – espresso_coffee Oct 26 '17 at 18:43
  • That certainly need bit more investigation. May be some extra spaces in your data ( while putting it into structue from query). – Keshav jha Oct 26 '17 at 18:50
  • Like I mentioned above this value: 0000 is causing error. – espresso_coffee Oct 26 '17 at 18:58

1 Answers1

2

I don't think there is anything wrong with your code, there is just lots wrong with serializeJSON in ColdFusion.

One trick / hack to force CF9 to treat all numeric-ish values as strings is to append non numeric text to the value and strip it off before using it client side. I have used the ASCII control character 2, "Start of Text", in the past. I like using a control character over other text for I feel safe that my users wouldn't intentionally use it.

To append the control character to your building number, just add chr(2) & before getBldg.number. On your client side, you can instruct jQuery to remove the control characters from the JSON string with the dataFilter property.

$.ajax({
    type: 'POST',
    url: 'Application.cfc?method=getBuildings',
    data: {},
    dataType: 'json',
    dataFilter: function(data, type){
        //Remove all start of text characters
        return data.replace(/\u0002/g,"");
    }
})
Twillen
  • 1,458
  • 15
  • 22