Solved

Coldfusion Ajax CFC - returning data

Posted on 2013-01-14
17
932 Views
Last Modified: 2013-01-15
Hi,
I need to write a quick remote cfc for a client side JQuery request for 4 fields on a table.

I will get 1 parameter sent to me "image file name" and I will return 4 columns from a table to be moved by the Jquery to 4 text fields.

<cffunction name="imageData"  access="remote" returnType="any" output="no">
      <cfargument name="imageKey" type="any" default="">

<cfquery name="getImage" datasource="myappdsn">
  Select column1, column2, column3, column4
   from Slide  where imageFile = #arguments.imageKey#

<CFreturn ??????>

</cffunction>

Open in new window


Q:   How do I return the data to the Jquery call?  Do I create a JSON string?  How do I do that?

For extra credit, how does the JQuery code parse this data to populate 4 text fields on the page?

Thanks in advance,
hefterr
0
Comment
Question by:hefterr
  • 6
  • 6
  • 5
17 Comments
 
LVL 10

Assisted Solution

by:stu215
stu215 earned 200 total points
ID: 38774914
<cffunction name="imageData"  access="remote" returnType="any" output="false" returnformat="JSON">


<!--- convert to json --->
 <cfreturn serializeJSON(yourResult)>

You can return data in a variety of ways it just depends on how you read it in when it gets back.
( Firefox with Firebug installed helps a lot for debugging and seeing return results. )

You could also do:
<cffunction name="imageData"  access="remote" returnType="query" output="false" returnformat="JSON">

<cfreturn yourQueryName>

The jQuery.get function should handle your restults:
http://api.jquery.com/jQuery.get/

 url - the cfc you are submitting to
data - being sent to cfc
callback - what function to run or to do when the data comes back
"Json" - the data type being transmitted

jQuery.get(url, data, callback, "json");
0
 
LVL 52

Accepted Solution

by:
_agx_ earned 300 total points
ID: 38775002
(I'm not a jquery guru, but since I had already written this starter example before seeing stu's response, may as well post it ;-)

Test

/test/MyComponent.cfc
<cfcomponent>

	<cffunction name="imageData"  access="remote" returnType="any" output="no">
     	<cfargument name="imageKey" type="any" default="">

		<cfset var result = {} />
		<cfset var row = "" />
		
		<!--- (testing only) simulate your db query --->
		<cfset var getImage = queryNew("")>
		<cfset queryAddColumn(getImage, "column1", listToArray("Value 1"))>
		<cfset queryAddColumn(getImage, "column2", listToArray("Value 2"))>
		<cfset queryAddColumn(getImage, "column3", listToArray("Value 3"))>
		<cfset queryAddColumn(getImage, "column4", listToArray("Value 4"))>
		
		<cfloop query="getImage">
			<!--- MUST use struct["keyName"] syntax to preserve case ---> 
			<cfset row = {}>
			<cfset row["column1"] = column1 >
			<cfset row["column2"] = column2 >
			<cfset row["column3"] = column3 >
			<cfset row["column4"] = column4 >
			<cfset result["data"] = row>
		</cfloop>
		
		<cfreturn result>
	</cffunction>
</cfcomponent>

Open in new window


<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>	
<script type="text/javascript">
$(document).ready(function() {
		$("#testButton").bind("click",function() {
			var key = document.getElementById('imageKey').value;
			var request = $.ajax({url: "/test/MyComponent.cfc?method=imageData&returnFormat=json"
								, type: "get"
								, dataType: "json"
								, data: {imageKey : key}
					});
			request.done( function(data) {
				populateFields(data);
			});
			request.fail( function(jqXHR, status) {
				alert("Failed: "+ status);
			});
		});
	});

function populateFields(response) {
	alert(response.data);
	if (response.data) {
		$("#field1").val(response.data.column1);
		$("#field2").val(response.data.column2);
		$("#field3").val(response.data.column3);
		$("#field4").val(response.data.column4);
	}
}	
</script>

</head>
<body>
	imageKey <input id="imageKey" type="text">
	<input id="testButton" type="button" value="Test" ><hr>
	
	<input id="field1" type="text"><br>
	<input id="field2" type="text"><br>
	<input id="field3" type="text"><br>
	<input id="field4" type="text"><br>
</body>
</html>

Open in new window

0
 
LVL 1

Author Comment

by:hefterr
ID: 38776474
@agx,
1)  Could you give me an overview of what you are building.  It looks like a CF structure "result" that has one key item (result.data)?  This contains another structure called "row" which contains row.column1, row.column2,row.column3 and row.column4?

Q:  Why does this ned to be built this way?

Q:  How can I see the result.  Can I use CFHTTP in a test program?

Q:  Do I need to indicate JSON in my CFC anywhere?

2)  Is the reference to :
                  request.done( function(data) {
                        populateFields(data);
                  });

tie back to the structure "data" or is that a JQuery special reference?

Thanks!
hefterr
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38776908
(Sorry I got caught up in other stuff...)

an overview of what you are building

"row" is just a temporary value used in construction. The actual result returned is a structure that contains a key named "data". "data" is itself a structure which contains 4 keys - one for each of the columns in your query.   ie  result.data.column1, result.data.column2, etc...  Here's what the json looks like

{"data":{"column4":"Value 4","column2":"Value 2","column3":"Value 3","column1":"Value 1"}}

Open in new window



Q:  How can I see the result.  Can I use CFHTTP in a test program?

You can view the results in your browser. Just adjust the url to match the path of your cfc:

   http://localhost/test/MyComponent.cfc?method=imageData&returnFormat=json&imageKey=someValueHere

Q:  Do I need to indicate JSON in my CFC anywhere?

You can, but don't *need* to. It's already done in the jquery url by adding the param:

           &returnFormat=json

(Doing it via url makes the function more flexible)

Q:  Why does this ned to be built this way?

Again, you don't *have* to build it that way. I chose that structure based on some assumptions about your process, like query returns 1 row of data, etc.. But you could easily structure it differently.  

tie back to the structure "data" or is that a JQuery special reference?

Neither. The name "data" is just a coincidence. You can assign any variable name, for example, I could have used "foo":

                  request.done( function(foo) {
                        populateFields(foo);
                  });

> alert(response.data);

BTW, you can remove that line. It was just for testing.
0
 
LVL 1

Author Comment

by:hefterr
ID: 38778329
@both

Stu simply returned the query itself.  Does this change the JQuery fielding the results?  What type of JSON does this produce?

agx packaged a structure.

Is there a good reason for one versus theother.

I really learned a lot from this post.  This is my first time using our own JQuery/AJAX.

hefterr
0
 
LVL 10

Expert Comment

by:stu215
ID: 38778923
Check out this link which explains the "serializeJSON" function and shows what the query return would look like: ( has an example + the output )

http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_s_03.html
0
 
LVL 1

Author Comment

by:hefterr
ID: 38778965
Hi stu215.
I was under the impression that the returned data would automatically undergo a conversion to JSON if the calling JQuery script indicated as such.

But the link was helpful to how the conversion is done for different data structures in CF.

hefterr
0
 
LVL 10

Expert Comment

by:stu215
ID: 38779007
I didnt have an example at the time but this is what a straight query return would look like:

<cffunction name="getEmps" output="false" access="remote" returntype="any" returnformat="JSON">
        <cfargument name="myDeptID" type="string" required="yes" default="">

        <cfquery name="getPeeps" datasource="general" maxrows="4">
           ... my Query ...
          </cfquery>

        <cfreturn getPeeps>
 </cffunction>  

The Results:

{"COLUMNS":["MYNAME","USERNAME","CUST_ID","FLAG"],"DATA":[["Abd, sha","abdsha444",null,"Y"],["Abc, Mike","Abc666 ",null,"Y"],["Ada, Jay","Ada555 ",null,"Y"],["Air, Kat","AirK222 ",null,"Y"]]}
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 52

Expert Comment

by:_agx_
ID: 38779379
Does this change the JQuery fielding the results?  What type of JSON does this produce?

The JSON is the same, only the structure of the result ie keys are different.

agx packaged a structure...
Is there a good reason for one versus the other.


You can do either. The advantage of just returning a query is it's simpler to code on the CF side. But the disadvantage is CF automatically converts all the keys to upper case, which is non-standard. (By that I just mean different than most of your typical API's, but the json is still perfectly valid). Because javascript is case sensitive, the consuming code must also use all upper case. Both work, its just a matter of what result you want.

I was under the impression that the returned data would automatically undergo a conversion to JSON if the calling JQuery script indicated as such.

It does. Adding   &returnFormat=json to the URL automatically converts the result to JSON.  So you can use the function multiple ways. Just add the url param when you want JSON. You could also use serializeJSON inside the function, but then it will always return JSON, making it a little less flexible.
0
 
LVL 1

Author Closing Comment

by:hefterr
ID: 38779407
Thanks for your help on this.  I may have other questions - but I'll open them up in another question or to the JQuery forum if needed.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38779521
Welcome.

     > CF automatically converts all the keys to upper case

(Edit) Two things I forgot to stress.  That applies to any structure. The only way to force CF to preserve the case of structure keys is to use this syntax (Dot notation *won't* work)

               <cfset yourStruct["keyName"] = "something">

Second,  the "&returnFormat=json" param has nothing to do with jquery. It's pure CF. CF sees that parameter in the URL and automatically converts the response to json format.
0
 
LVL 1

Author Comment

by:hefterr
ID: 38780038
@agx,
The only way to force CF to preserve the case of structure keys
This is a very lame question, but do you mean the "case" of the key name or the "case" of the key value.  I assume you are referring to the case of the value.
0
 
LVL 10

Expert Comment

by:stu215
ID: 38780062
Agx is referring to how the data is returned from the CFC:

This is how it should look:
{"data":{"column4":"Value 4","column2":"Value 2","column3":"Value 3","column1":"Value 1"}}

Coldfusion would make it all caps ( Caps are not standard ) and programs will have issues.

You can kinda see this from my data return using CF:
{"COLUMNS":["MYNAME","USERNAME","CUST_ID","FLAG"],"DATA":[["Abd, sha","abdsha444",null,"Y"],["Abc, Mike","Abc666 ",null,"Y"],["Ada, Jay","Ada555 ",null,"Y"],["Air, Kat","AirK222 ",null,"Y"]]}
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38780067
The key name. If you create a structure with dot notation:
              <cfset myStruct.someKeyName = "foo">

When CF converts it to json, it will look like something like this:
             { SOMEKEYNAME: "foo" }

But if you used this syntax:

              <cfset myStruct["someKeyName"] = "foo">

CF will preserve the exact case of the key name and the json result will be:

             { someKeyName: "foo" }
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38780070
Oops, sorry guys.  Took too long typing and our responses overlapped,
0
 
LVL 10

Expert Comment

by:stu215
ID: 38780081
Sall good :-P

-- You can handle it on the return side if you want but generally its easier to return standard data & to do any processing to your data before returning it.
0
 
LVL 1

Author Comment

by:hefterr
ID: 38780321
You guys re GREAT!  Big help getting into CF/JQuery/AJAX.  I am working with a front end colleague doing the JQuery - but she is a bit new to this also.  So thanks again,

hefterr
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Airline check in kiosk 4 99
Fixing Old Legacy Code 1 26
How to get javascript to talk to coldfusion in < 3 page loads 4 36
Coldfusion - rename files in a folder 4 10
Hi, I will be creating today a basic tutorial on how we can create a Mail Custom Function and use it where ever we want. The main advantage about creating a custom function is that we can accommodate a range of arguments to pass to the Function and …
This is an updated version of a post made on my blog over 3 years ago. It is unfortunately, still very relevant as we continue to see both SQLi (SQL injection) and XSS (cross site scripting) attacks hitting some of the most recognizable website and …
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now