CFML How to get status code from an ajax response - ajax

I am almost done making a web app with CFML but I have a question on handling errors. For example, a part of my web app can execute user entered SQL code. However if the SQL code the user provides isn't valid then it will not execute properly and I get an error like this:
https://devintranet.dep.gov/oogns/sharedComponents.cfc 500
Which makes sense. If it helps answering my question at all here is the information on the network tab:
All I want is to be able to catch when the status code returns 500 and be able to take action based on that. For example if I make a request that ends up having a status code of 500 then I can use JS alert to tell the user something went wrong.
Here is the function in sharedComponents.cfc:
<cffunction name="LoadAttribute" access="remote" returnformat="plain" returntype="string" >
<cftry>
<cfquery name ="AttributeQuery" datasource="RBDMS_UPDATE">
SELECT *
FROM dbo.OOGNS_Queries
WHERE UPPER(QueryName) = UPPER(<cfqueryparam cfsqltype="varchar" value="#form.default_ProfileName#" />)
</cfquery>
<cfcatch>
<cfoutput>
#cfcatch.Detail#<br />
#cfcatch.Message#<br />
#cfcatch.tagcontext[1].line#:#cfcatch.tagcontext[1].template#
</cfoutput>
</cfcatch>
</cftry>
<cfreturn AttributeQuery["#default_ColName#"][1] />
</cffunction>
And here is the ajax function that calls it:
$.ajax({
type: "POST",
url: "sharedComponents.cfc",
data: { method: "LoadAttribute",
default_ProfileName: ProfileName,
default_Entity: Entity,
default_ColName: ColName,
},
datatype: "json"
}).done(function(returnresult) {
There is actually a lot of code after that but I believe it to be irrelavent to what I'm trying to do. Literally if you can show me how to obtain the status code from the response header I think I'll be good.

There are two separate issues in your request.
Catch errors on server side
It can be that the requested column is not available in the AttributeQuery result. So you have to check for that before accessing it.
One way to do this is:
<cfreturn structKeyExists(AttributeQuery, default_ColName) ?
AttributeQuery[default_ColName] : "" />
Catch errors on client side
To catch HTTP errors you can use the error() function jQuery's ajax() function provides, as Miguel-F and AndreasRu mention in their comments.

Related

Two jQuery Ajax Calls in a coldfusion page

I am new to jQuery API documentation and hence wondering if the following scenario is possible:
So far, I have come across only one Ajax call in one coldfusion page.
Scenario:
I am sending a $.ajax call to a cfc to call a method in a CFC and returning the data back in JSON format. Basically the method I am calling here will be adding the data into the database.
I want to write another $.ajax call to call a method in a CFC, which will read the data which is saved by the above ajax call and display in JSON format on the Web Browser.
So, my questions is, can I go for multiple ajax call in a single coldfusion page as long as Iam doing this in sequential manner?
Sequential order must be the key, am I right?
Please clarify !!
Thanks
There's two ways to go about it really...
A jQuery AJAX call has a callback function to it, so you could simply get some JSON back from the initial submission and from that callback fire off the second request - that way you can be sure the first action has completed before you call the second.
var request = {
returnformat : 'json',
queryformat : 'column',
method: 'save_data',
data: /* data to pass to the save action here */
}
$.getJSON("path/to/your/service.cfc", request, function(response) {
var request = {
returnformat : 'json',
queryformat : 'column',
method: 'get_data'
}
$.getJSON("path/to/your/service.cfc", request, function(response) {
/* code to fire on response */
});
});
However I think a better way would be to make a single AJAX call and simply do both the submission save and the data response in one CFC method. Your CFC might look something like this:
<cffunction name="save_response" access="remote" output="false">
<cfset response = structNew()>
<cfset response.status = true>
<cftry>
<cfquery datasource="#datasource#">
INSERT...
</cfquery>
<cfquery datasource="#datasource#" name="get_data">
SELECT...
</cfquery>
<cfset response.data = get_data>
<cfcatch type="any">
<cfset response.status = false>
</cfcatch>
</cftry>
<cfreturn response>
</cffunction>

ReturnFormat row when POSTing CFAJAX request

I'm struggling with the setQueryFormat() call to an AJAX-function in CF9. I have CFM-File that looks like so:
<div id="div1" onclick="callfkt1('POST');" style="cursor:pointer;">POST</div>
<div id="div2" onclick="callfkt1('GET');" style="cursor:pointer;">GET</div>
<script type="text/javascript">
function callfkt1(sHTTPMethod) {
var oTester001=new CTester001();
oTester001.setCallbackHandler(function(result) {
alert(JSON.stringify(result));
});
oTester001.setErrorHandler(function(err, msg) {
alert(err + ': ' + msg);
});
oTester001.setHTTPMethod(sHTTPMethod);
oTester001.setQueryFormat('column');
oTester001.fkt1();
}
</script>
Tester001.cfc contains the following:
<cfcomponent >
<cffunction name="fkt1" returntype="query" access="remote">
<cfquery name="local.queries.qry1" datasource="brdwr">
SELECT url_id, url
FROM urls
</cfquery>
<cfreturn local.queries.qry1>
</cffunction>
</cfcomponent>
When I call the JavaScript function With parameter 'GET' the result is returned in query format 'column' which means it contains a ROWCOUNT member that stores the number of records returned from the query. Using request method 'POST' the recordset is returned in format 'row' without ROWCOUNT member. Have you experienced this? Do you limit to GETing CFAJAX request?
Best.
You might try changing your CFC so that you explicitly declare how you want the JSON returned by using the serilizeJson function:
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_a-b_3.html
As the second argument of the function, you can set serializeQueryByColumns to True, so that it will serialize the data as a WDDX query format, which is what the setQueryFormat("column") is supposed to do.
While not an answer, do know that when the row format is used, you still get the same data. It's in a different format, but you still get all the data. You just have to work with it differently.

calling a coldfusion function from another function via ajax rendering an error

Here's the deal: I am sending an ajax request to a coldfusion function, which then calls another function inside the same component. Here are the two functions:
<!--- test--->
<cffunction name="deleteMission" access="public" output="No" returntype="struct">
<cfscript>
var returnData = structNew();
structAppend(returnData, getTest());
returnData.test2 = "test2";
</cfscript>
<cfreturn returnData>
</cffunction>
<!--- test2 --->
<cffunction name="getTest" access="public" output="No" returntype="struct">
<cfscript>
var returnData = structNew();
returnData.testing = "TEST";
</cfscript>
<cfreturn returnData>
</cffunction>
Very simple, just returning 2 struct keys in this example. If I call the method test() regularly (ie, on page load via coldfusion), I get the expected results. However, if I call the method test() via AJAX, I receive the error "Variable getTest is undefined." If I remove the call to getTest(), I receive the single struct key back as expected. Anyone have any idea what is going on? I have a feeling it's something simple I've overlooked, but I need some more eyeballs on it at this point... I'm really scratching my head on this one. Thanks!
If you're accessing the component via AJAX, then the access attribute of your cffunction should be set to remote. E.g.
<cffunction name="deleteMission" access="remote" output="No" returntype="struct">
Change your getTest to access="private".
Also, Sometimes the StructAppend method does not take in parameters as "function call". So get the value into a variable first and then send that variable to deleteMission.
something like this...
var inpData = getTest();
structAppend(returnData, inpData);

How do I pass an onclick argument to a CFC to update the database through AJAX?

New to Ajax. Just trying to do a simple ajax/cfc vote yes/no app. Can’t get it to work
What I am trying to accomplish is a simple Vote "Yes or No" app where it shows the number of votes cast next to each link. For example:
Yes (882 votes)
No (163 votes).
When a visitor votes, the database should be updated with the vote and record the voter in a different table (so they can't vote again). Finally, a confirmation message is displayed with the new vote count:
You voted "Yes" (883 votes) or
You voted No (164 votes)
Now I had everything working but updating the database. I tried reworking the JavaScript (AJAX) to call a CFC by adding ($.ajax) and moving the response messages within the ajax part. However, now it’s not working at all. What did I do wrong?
Below is the new code I came up with. To keep this question simple, I am just showing the "No" Vote portion. Am I on the right track? This seem like it would be very simple.
Voting link
<A HREF="javascript:()" onclick="VoteNoID('#IdeaID#');">
<SPAN ID="VoteNoMessage">No</SPAN>
</A>
- <SPAN ID="NewNoCount">#NoCount#</SPAN>
Ajax
<script LANGUAGE="JavaScript">
function VoteNoID()
{
var VoteNoDescription = document.getElementById("VoteNoDescription").style.display='none';
$.ajax({
type: "POST",
url: "../CFC/VoteNo.cfc?method=VoteNoID",
data: recordata,
dataType: "html",
success: function(message) {
$('#VoteNoMessage').html("you voted No");
$('#NewNoCount').html("#NewCount#");
}
});
});
} `
<script>
VoteNo.cfc
<cffunction name="NoVote" access="remote" returntype="string"
<cfargument name="VoteNo" type="string" required="yes">
<CFQUERY NAME="NoCountCK" DATASOURCE="MyDSN">
SELECT *
FROM Ideas
WHERE IdeaID = #arguments.VoteNo#
</CFQUERY>
<CFSET NewCount=#NoCountCK.NoCount#+1>
<CFQUERY NAME="UpdateNoCount" DATASOURCE="MyDSN">
UPDATE Ideas
SET NoCount = #NewCount#
WHERE IdeaID = #arguments.VoteNo#
</CFQUERY>
<CFQUERY NAME="MemberVote" DATASOURCE="MyDSN">
INSERT INTO MemberVoteRecord(IdeaID,MemberID,DatePosted,YesNo)
VALUES(#arguments.VoteNo#,#COOKIE.Member_ID#,#NOW()#,N)
</CFQUERY>
<cfreturn NewCount>
</cffunction>
The success part of our .ajax() call is just setting the html to be the variable #newcount#. I'm not sure where that variable is being set initially, but if you would look at your raw html generated, you will see that the raw html contains a static number here. You need to set this as a javascript variable, not a ColdFusion variable.
So, try setting this variable to be message, which is the argument passed to your success call back. Message should be equal to whatever your CFC is returning. I.e. if you would call the CFC directly in the browser, this is what your browser would render.
success: function(message) {
$('#VoteNoMessage').html("you voted No");
$('#NewNoCount').html(**message**);
}
Also, you'll want to adjust your CFC function's return format to be "plain". .

Set session variable with select box via jQuery/ Ajax with Coldfusion

Ok so here is my epic journey problem going on for a month now...:
First problem: I was building a form with coldfusion-ajax tags which was the worst mistake ever. IE completely hates it and I was unable to bind anything. YES, my code was correct. I had it verified by many people and many forums. So I have NO IDEA what was wrong.
So coldfusion ajax tags are out of the question..they won't work with my server setup...I don't know. (I don't control my server I work on)
So...now that i'm SOL and crying in my office like a crazy person... I have now decided to go around the problem by using jQuery + Coldfusion.
It isn't working either...
Here is the new problem:
I need to have a select box that was pre-populated set a session variable. In other words:
I want to pass a form variable to a page that will set the session variable equal to that form variable...
Note: I'm using CF 8.
Here is my code so far:
form:
<form>
<select name="DeptCode" id = "dept">
<option value="NONE" selected>Choose a Department
<cfoutput query="getDepartments">
<option value="#DeptCode#">#DeptName#</option>
</cfoutput>
</select>
</form>
<cfoutput> #session.DeptCode#</cfoutput>
jQuery/Ajax:
<script language = "javascript">
$('#dept').change(
function() {
var datas = $('#dept').val();
$.ajax({
url: 'url:catch.cfc?method=getDept',
data: {dept: datas}
success: function(datas) { alert(datas); }
});
});
</script>
catch.cfc
<cfcomponent output="false">
<cffunction name="setDept" access="remote" returntype="any">
<cfargument name="dept" type="any" required="yes">
<cfset session.DeptCode = #argument.dept#>
<cfreturn />
</cffunction>
</cfcomponent>
I'm not sure if you've updated things since posting your code, or maybe there were typos during transcription -- but there are some syntax problems:
$('#dept').change( function() {
var datas = $('#dept').val(); // always yields a result in real code?
$.ajax({
url: 'catch.cfc?method=getDept', // You repeated "url:" in your url
data: {dept: datas}, // added missing final comma
success: function(datas) { alert(datas); }
});
});
Just a thought.

Resources