Aliaspooryorik
ColdFusion ORM Book

JSON Case Issue between CF8 and CF9

I wrote a quick demo for Devon CFUG this week to demonstrate using jQuery, AJAX and ColdFusion together to build a simple "find as you type" search feature. However it turns out that ColdFusion 8 and ColdFusion 9 return slightly different JSON.

Here is the cfcomponent


<cfcomponent output="false">

<cfsetting enablecfoutputonly="true" showdebugoutput="false">

<cffunction name="findCity" access="remote" output="false" hint="returns a query object as json">
<cfargument name="searchfor" required="true" type="string">

<cfset var cities = $fakequery()>
<cfset var result = "">

<cfquery name="result" dbtype="query">
SELECT id, name
FROM cities
WHERE Lower(name) LIKE <cfqueryparam value="%#Trim( LCase( arguments.searchfor ) )#%" cfsqltype="cf_sql_varchar">
ORDER BY name
</cfquery>

<cfreturn result>
</cffunction>

<cffunction name="$fakequery" access="private" returntype="query" output="false">
<cfset var query = QueryNew( "id,name" )>
<cfset var i = 0>
<cfset var cities = ListToArray( "Accra,AddisAbaba,Adelaide,Aden,Alexandria,Algiers,Amsterdam,Ankara,Athens,Auckland,Baghdad,Bahrain,Baltimore,Bandung,Bangkok,Barbados,Beijing,Beirut,Belgrade,Bermuda,Berlin,Berne,Bogota,Bombay,Bonn,Boston,Brazzaville,Brisbane,Brussels,Bucharest,Budapest,BuenosAires,Cairo,Calcutta,Canberra,Caracas,Cassablanca,Chicago,Chongqing,Cologne,Colombo,Copenhagen,Dacca,Dallas,Damascus,Dar-es-Salaam,Darwin,Delhi,Detroit,Dhahran,Dubai,Dublin,Entebbe,Frankfurt,Geneva,Georgetown,Gibralta,Guangzhou,Hamburg,Hanoi,Havanno,Helsinki,Hobart,HoChiMinhCity,HongKong,Honolulu,Houston,Islamabad,Istanbul,Jakarta,Jeddah,Kabul,Karachi,Katmandu,Khartoum,Kingston,Kinshasa,KualaLumpur,Kuwait,Kyoto,Lagos,Lahore,Leningrad,Lima,Lisbon,London,LosAngeles,Lusaka,Madras,Madrid,Malta,Manila,Mauritius,Melbourne,MexicoCity,Miami,Milan,Montevideo,Montreal,Moscow,Munich,Nairobi,Nadi,Naples,NewOrleans,NewYork,Nicosia,Osaka,Oslo,Ottawa,PanamaCity,Paris,Perth,Philadelphia,Pittsburgh,PortMorsby,Prague,Pusan,Pyongyang,Quebec,RiodeJaneiro,Rome,Rotterdam,StLouis,StLucia,StPetersburg,SanFrancisco,Santiago,SaoPaulo,Seoul,Seychelles,Shanghai,Shenyang,Singapore,Sofia,Stockholm,Suez,Sydney,Taipei,Tehran,Tianjin,Tokyo,Toronto,Tunis,Trinidad,Vancouver,Vaeletta,Vienna,Warsaw,Washington,Wellington,Winnepeg,Wuhan,Xian,Yangon,Yokohama,Zurich" )>

<cfloop from="1" to="#ArrayLen( cities )#" index="i">
<cfset QueryAddRow( query )>

<cfset QuerySetCell( query, "id", i )>
<cfset QuerySetCell( query, "name", cities[ i ] )>
</cfloop>

<cfreturn query>

</cffunction>

</cfcomponent>

Running on ColdFusion 9, I used this jQuery


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ColdFusion AJAX with jQuery</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
// <![CDATA[
$(function(){
// DOM is ready

/*
--------------------------------------------------------
Cities AJAX search
--------------------------------------------------------
*/


// create a reference to save getting from jQuery each time
$citysearch = $('#citysearch');

/*
because we want to enhance non-javascript version create the results
list and insert it after the search box using jQuery
*/

$matcheslist = $('<ul id="searchmatches" />')
.hide()
.insertAfter($citysearch);

// add keyup event listener to the input text box
$citysearch
.keyup(function(event){
// ignore printable character or backspace presses
if (event.keyCode>
40||event.keyCode==8){
$this = $(this);
if ($.trim($this.val())==''){
// no text so remove previous matches
$matcheslist.empty();
}
else{
// text entered so get data from server
getMatches();
}
}
});


// this function calls the CFC and expects a JSON response
var getMatches = function(){
$.getJSON(
'Remote.cfc',
{
method:'findCity',
returnformat:'json',
queryformat:'column',
searchfor:$.trim($citysearch.val())
},
showMatches
);
}

// this method processes the JSON response from the CFC
var showMatches = function(json){
// if you use Firebug or Chrome you can view the data for debugging - remove on live site
console.log( json );

// remove all previous 'li' elements
$matcheslist.empty();
// check if any matches
if (json.ROWCOUNT==0) {
// no matches so create a friendly message
$('<li></li>').text('no matches found')
.appendTo($matcheslist);
}
else {
// loop through the returned rows
for (var i=0; i<json.ROWCOUNT; i++) {
// create list item element with matching city name.

$('<li></li>')
.html('<a href="citydetail.cfm?id=' + json.DATA.ID[i] + '">' + json.DATA.NAME[i] + '</a>')
.appendTo($matcheslist);
}
}
// make the list of matches visible (if hidden)
$('#searchmatches').show();
}
});
// ]]>

</script>
</head>
<body>

<form action="#" method="post">
Find City: <input type="text" id="citysearch" />
</form>

</body>
</html>

So my demo went well and everyone gasped (OK, so I might have exagerated a bit). The thing is, on my ColdFusion 8 it doesn't work. This is because, ColdFusion 9 returns the DATA.ID and DATA.NAME; ColdFusion 8 return DATA.id and DATA.name. It's a small difference, and easy enough to fix, but as JavaScript is case-sensitive it broke my demo. Did I miss something?

 


3 comments

  1. That is odd. It must have to do with the fact that you are manually creating the query. As you probably know, when you use array notation to create a struct key, it will maintain case... now, how does that apply in this situation? I have no idea :) It must be that they have updates the query creation in CF9 to have some of that functionality.

    Very odd.

    Comment by Ben Nadel – February 06, 2010
  2. Seen the same thing. I pull some RSS feeds and return them as JSON. My Dev env is CF9 and my prod is still CF8 (soon to be upgraded). Made some changes the other day and ran into the same casing issue.

    Is there a way to control that? With a Flex remoting call you can set it in the channel definition via the services-config.xml file. Does the CF Admin have a similar feature?

    Comment by molaro – May 12, 2010
  3. @molaro, there isn't a setting in the CFIDE that I know of. You can force ColdFusion to use a particular case for a variable name if you use this syntax:

    variables['uppercase'] = 'somevalue';

    Comment by John Whish – May 12, 2010

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.

Please subscribe me to any further comments
 

Search

Wish List

Found something helpful & want to say ’thanks‘? Then visit my Amazon Wish List :)

Categories

Recent Posts