cfwheels Find Records and Output as JSON Encoded - coldfusion

I am new to ColdFusion, currently using CFWheels Framework. I have a snippet that send a ajax request from the view using jquery post with two parameters name and time.
$(".building").on("blur", function() {
$.post("index.cfm/audit/building", { name: "John", time: "2pm" })
.done(function( data ) {
alert( "Data Loaded: " + data );
});
});
My controller action
<cffunction name="building">
<cfscript>
categories = model("buildings").findByKey(params.name);
test = params.name & params.time;
renderText(test);
</cfscript>
</cffunction>
My Model
<cfcomponent extends="Model">
<cffunction name="init">
<cfset table("buildings")>
<cfset hasMany("rooms")>
</cffunction>
</cfcomponent>
I wish to do a simple task as following
check if any building by passed name exist in database
if so then return the row in json format, like echo json_encode in php
else create new record and redirect to another action with params
I am stuck on step 1, and its telling me
The value for cfqueryparam cannot be determined
What does this mean? Please help, also if anyone can also tell me how to render query data in json form for jquery post to read.

just sharing the answer.
<cffunction name="building">
<cfscript>
buidling = model("buildings").findOneByName(params.name);
if(IsObject(buidling)) {
//return json format
renderText(SerializeJSON(buidling));
} else {
//enter new record
new_building = model("buildings").new();
new_building.name = params.name;
new_building.save();
//return id json
renderText(SerializeJSON(new_building));
}
</cfscript>
</cffunction>

Related

How to catch a ColdFusion CFHTTP timeout exception?

I have a page where I make a remote request to an external API. I sometimes get request timeouts when making the request, so, my plan to set a timeout in the CFHTTP tag that is lower than my default requesttimeout setting and catch it. However, I can't get my CFTRY/CFCATCH to catch it. Here is my pseudo code:
private void function makeRequest(){
cfhttp(
url="https://api.somesite.com/",
method="POST",
timeout="1",
throwonerror="true",
result="LOCAL.ApiHttpResult"
) {
...
}
}
public void function tryRequest() {
try {
makeRequest();
}
catch(coldfusion.runtime.RequestTimeoutException e) {
abort;
}
}
I get the same result out of CFSCRIPT:
<cffunction access="public" returntype="void" name="tryRequest">
<cftry>
<cfscript>
makeRequest();
</cfscript>
<cfcatch type="coldfusion.runtime.RequestTimeoutException">
<cfabort />
</cfcatch>
</cffunction>
Is there something special about the CFHTTP timing out that makes this impossible to catch programmatically? Any ideas on how to do this?
Thanks....
You just misspelled the exception type: It's coldfusion.runtime.RequestTimedOutException (coldfusion.runtime.RequestTimedOutException).
But there's another way to do this without exception handling. Just do a regular cfhttp, but don't specify the throwOnError attribute (or keep it false). This will still return a response struct after the request has timed out. It will be populated with status code 408 Request Time-out. You can access it like this:
if (left(LOCAL.ApiHttpResult.Statuscode, 3) eq "408") {
writeOutput("HTTP request timed out");
} else {
writeOutput("HTTP request successful with status: #LOCAL.ApiHttpResult.Statuscode#");
}
More of a comment, but this is way too long. Just do a dump off whatever exception is happening. Then filter on the specific exception
public void function tryRequest() {
try {
makeRequest();
}
catch(any e) {
writedump(e);
// then find the details on the specific exception type
}
}

How can I send HTTP Status Code and a Response messages to the client in ColdFusion?

I am implementing the Single Sign On functionality. I have an ColdFusion application which takes input parameters from Java application (POST request). What I need to do is return status codes and a description to indicate whether the user has access and the failed reason if the user does not have access to my CF application.
Something like below:
I have created a cfc and provided this as an API to allow Java users to pass in their UserName, CustomerID to my CF application.
Do I need to write the return response logic in the same file? Like a function which "throw" error code (cfthrow).
Or may be I can use "cfheader"....something like this:
<cfif form.CustomerId EQ queryname.CustID>
<CFHEADER
STATUSCODE="200"
STATUSTEXT="Success">
<cfelse>
<CFHEADER
STATUSCODE="400"
STATUSTEXT="Insufficient Input">
</cfif>
Can anyone please help me here?
You can use:
component restpath = "your/rest/path" rest="true"
{
remote void function errorTest()
httpmethod = "GET"
restpath = ""
{
cfheader(
statuscode = 401,
statustext = "Invalid Password"
);
// or
restSetResponse({
status = 401,
headers = { explanation = "Invalid Password" }
});
// or, using Java
getPageContext()
.getResponse()
.getResponse()
.sendError( JavaCast( 'int', 401 ), "Invalid Password" );
// or, using the deprecated setStatus(int,string) method in Java
getPageContext()
.getResponse()
.getResponse()
.setStatus( JavaCast( 'int', 401 ), "Invalid Password" );
}
}
Note: I have not found a way to directly set the message using restSetResponse() so this returns a custom header with the message instead.

cflocation and session variables

My user comes from a 3rd party site via http post with login credentials encrypted in the URL.
Once the index.cfm recognizes these variables, it sends the request to:
<cflocation url="login.cfm?vals=#URLEncodedFormat(url.vals)#" addtoken="yes">
The login.cfm builds a session struct if the login credentials are valid.
Session.user.userID = 1;
Session.user.firstName = "jo";
Session.user.lastName = "boo";
Then, it does:
<cflocation url="somepage.cfm" addtoken="yes">
When I dump the session variable in somepage.cfm, I do not see the session.user struct. Also, I keep seeing different cfid, cftoken on somepage.cfm every single I refresh. I am on ColdFusion 10.
Any ideas? How can I keep the session.user?
Edit: application.cfc has
this.name = "My Application";
this.applicationTimeout = createTimeSpan(0,2,0,0);
this.clientManagement = true;
this.loginStorage = "session";
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,0,30,0);
this.setClientCookies = true;
this.setDomainCookies = false;
this.scriptProtect = "all";
this.javaSettings = {LoadPaths = ["#GetDirectoryFromPath(GetCurrentTemplatePath())#java/"], reloadOnChange=true, watchInterval=180};
EDIT: here are the files
http://1drv.ms/1kjnQO2
Unzip them to your C:\ColdFusion10\cfusion\wwwroot\
then go to :
http://localhost:8500/test/call.cfm
EDIT: 19:00 - 10Jun:
Wow, this really sucked! Came home, downloaded the zip, opened it up to localhost. When I run, I can see the session.user variables from call.cfm.
<cfdump var="#server#">
gives me:
coldfusion
struct
InstallKit Native Windows
appserver J2EE
expiration {ts '2012-10-30 10:35:35'}
productlevel Developer
productname ColdFusion Server
productversion 10,0,0,283111
rootdir C:\ColdFusion10\cfusion
I am not sure if this has something to do with the CF server version.
UPDATE: 09:00 11-Jun.
Once I disable "Use J2EE session variables " in CFAdmin, the session variables are visible to call.cfm. Now, I have to make it work with J2EE session variables when they are enabled.

Login with gmail account in Coldfusion

I want to login with gmail/google account and I found this tutorial Gmail Login in Coldfusion. I done All the steps and After login my page redirect then I want to display user Profile information so I dump this
<cfdump var="#session.profilesArray#">
but it gives me an empty array.why I am not getting my profile data after successfully lo-gin.
If I am getting wrong way for fetching my profile then what is correct way. Thanks.
You just add this line into your scope
Open your Application.cfc and then add this code
change scope = "https://www.googleapis.com/auth/analytics.readonly" with scope = "https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile
you can just add scope = "https://www.googleapis.com/auth/userinfo.profile but if u want to access email then add second one as I Post in my answer.
<cfset request.oauthSettings =
{scope = "https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile",
client_id = "Your-id",
client_secret = "your-secret",
redirect_uri = "redirect-page",
state = "optional"} />
Now you can get User Information from function that you can call like this
<cfscript>
public function getProfile(accesstoken) {
var h = new com.adobe.coldfusion.http();
h.setURL("https://www.googleapis.com/oauth2/v1/userinfo");
h.setMethod("get");
h.addParam(type="header",name="Authorization",value="OAuth #accesstoken#");
h.addParam(type="header",name="GData-Version",value="3");
h.setResolveURL(true);
var result = h.send().getPrefix();
return deserializeJSON(result.filecontent.toString());
}
</cfscript>
<cfoutput>
<cfset show = getProfile(session.ga_accessToken)>
<cfdump var="#show#">
</cfoutput>
Hope this will help you.

coldfusion uploadify http 302

I was using uploadify v2.1.4 for my coldfusion upload multiple files. It worked well in IE 9 but occured an error http 302 in firefox 5
$('#uploadfile').uploadify({
'uploader' : 'uploadify.swf',
'script' : './upload.cfm',
'cancelImg' : 'cancel.png',
'auto' : true,
'multi' : true,
'onError' : function(a, b, c, d) {
alert("Event: "+a+", QueueID: "+b+" FileInfo: "+c.name+", "+c.size+", "+c.creationDate+", "+c.modificationDate+", "+c.type+" Error: "+d.type+", "+d.info);
}
});
and my upload.cfm
<cfscript>
thisPath = ExpandPath("*.*");
thisDirectory = GetDirectoryFromPath(thisPath);
FileDir = thisDirectory & "uploads/";
</cfscript>
<cffile action="upload" filefield="fileData" destination = "#FileDir#" nameconflict="makeunique" mode="777">
When you're using uploadify, it will send a request from the flash player to the upload.cfm file. Unfortunately, it doesn't always send the session details to the upload.cfm file, so if you have any sort of authentication that could be blocking the request, then you'll get an error.
Verify that you don't have any authentication mechanisms in front of your upload file (and that you're not doing a cflocation, as Jason mentioned). If you do, then you'll either need to manually pass authentication credentials to your upload form, or remove the authentication requirements from that file. I usually use the scriptData property for Uploadify to send the details along to my upload script.