CFCs & CFInvoke
I am attempting to play with components and invoke them
inside web pages. I
created a simple CFC (news.cfc) to pull the latest news story
from the
database:
<cfcomponent>
<cffunction name="LatestNews" access="public"
returntype="string">
<cfargument name="myArgument" type="string"
required="false">
<cfquery name="news" datasource="#Request.MainDSN#">
SELECT News_ID, Story,"Date" FROM ms411.news ORDER BY "Date"
DESC
</cfquery>
<cfset myResult="foo">
<cfreturn MyResult>
</cffunction>
</cfcomponent>
In the web page I want to display the results I have:
<cfinvoke
component="news"
method="LatestNews"
returnvariable="returnVar">
</cfinvoke>
Then I have, in the area I want to display it:
<cfoutput query="returnVar">
<tr>
<td>#Date#</td>
</tr>
<tr>
<td>#Story#</td>
</tr>
</cfoutput>
I keep getting this error:
Attribute validation error for tag cfoutput.
The value of the attribute query, which is currently
"returnVar", is
invalid.
I have the Coldfusion MX Bible sitting next to me and (on
page 452 for those
of you that have it) it give the same example. Same invoke,
same 'cfoutput
query = "returnVar"''. Why am I getting this error and how do
I fix it?
Thanks!
Wally Kolcz
Developer / Support
As well as the returntype of your function being a string
instead of a
query.
<cffunction name="LatestNews" access="public"
returntype="string">
You are also not returning the query.
<cfquery name="news" datasource="#Request.MainDSN#">
<cfreturn MyResult>
That should be <cfreturn news> so that it returns the
query you created.
You can remove the <cfargument ...> line, since you are
not using it.
Unless you plan to add functionality later that would make
use of the value.
To jump start you an better practices. You should var declare
your news
variable so that it is local to the function and will not run
into
problems with other variables named "news" in other places of
your code.
<cfuntion ....>
<cfset var news = "">
Secondly you should pass in your dsn value to the function,
not have the
function relay on a value existing in the calling code block.
This
would then be a reason for a <cfargument ...> tag.
<cffunction ... returnType="query">
<cfargument name="DSN" requrired="true" ...>
<cfset var news = "">
<cfquery name="news" dataSource="#arguments.DSN#"...>
<cfreturn news>
</cffunction>
Your invoke then would add an argument parameter, there are
two ways you
could do this.
> <cfinvoke
> component="news"
> method="LatestNews"
> returnvariable="returnVar"
dsn="#request.MainDSN#">
> </cfinvoke>
OR
> <cfinvoke
> component="news"
> method="LatestNews"
> returnvariable="returnVar">
<cfinvokeArgument name="dsn" value="#request.MainDSN#">
> </cfinvoke>
Wally Kolcz wrote:
> I am attempting to play with components and invoke them
inside web pages. I
> created a simple CFC (news.cfc) to pull the latest news
story from the
> database:
>
> <cfcomponent>
> <cffunction name="LatestNews" access="public"
returntype="string">
> <cfargument name="myArgument" type="string"
required="false">
> <cfquery name="news"
datasource="#Request.MainDSN#">
> SELECT News_ID, Story,"Date" FROM ms411.news ORDER BY
"Date" DESC
> </cfquery>
> <cfset myResult="foo">
> <cfreturn MyResult>
> </cffunction>
> </cfcomponent>
>
> In the web page I want to display the results I have:
>
> <cfinvoke
> component="news"
> method="LatestNews"
> returnvariable="returnVar">
> </cfinvoke>
>
> Then I have, in the area I want to display it:
>
> <cfoutput query="returnVar">
> <tr>
> <td>#Date#</td>
> </tr>
> <tr>
> <td>#Story#</td>
> </tr>
> </cfoutput>
>
> I keep getting this error:
> Attribute validation error for tag cfoutput.
> The value of the attribute query, which is currently
"returnVar", is
> invalid.
>
> I have the Coldfusion MX Bible sitting next to me and
(on page 452 for those
> of you that have it) it give the same example. Same
invoke, same 'cfoutput
> query = "returnVar"''. Why am I getting this error and
how do I fix it?
>
> Thanks!
>
Similar Messages
-
I am attempting to play with components and invoke them
inside web pages. I
created a simple CFC (news.cfc) to pull the latest news story
from the
database:
<cfcomponent>
<cffunction name="LatestNews" access="public"
returntype="string">
<cfargument name="myArgument" type="string"
required="false">
<cfquery name="news" datasource="#Request.MainDSN#">
SELECT News_ID, Story,"Date" FROM ms411.news ORDER BY "Date"
DESC
</cfquery>
<cfset myResult="foo">
<cfreturn MyResult>
</cffunction>
</cfcomponent>
In the web page I want to display the results I have:
<cfinvoke
component="news"
method="LatestNews"
returnvariable="returnVar">
</cfinvoke>
Then I have, in the area I want to display it:
<cfoutput query="returnVar">
<tr>
<td>#Date#</td>
</tr>
<tr>
<td>#Story#</td>
</tr>
</cfoutput>
I keep getting this error:
Attribute validation error for tag cfoutput.
The value of the attribute query, which is currently
"returnVar", is
invalid.
I have the Coldfusion MX Bible sitting next to me and (on
page 452 for those
of you that have it) it give the same example. Same invoke,
same 'cfoutput
query = "returnVar"''. Why am I getting this error and how do
I fix it?
Thanks!
Wally Kolcz
Developer / Support
Wally Kolcz
Developer / Support
Wally Kolcz
Developer / Support
ProjectProofing.comThe extraneous "foo" confuses matters. Why not just do:
<cfcomponent>
<cffunction name="LatestNews" access="public"
returntype="query">
<cfargument name="myArgument" type="string"
required="false">
<cfquery name="news" datasource="#Request.MainDSN#">
SELECT News_ID, Story,"Date" FROM ms411.news ORDER BY "Date"
DESC
</cfquery>
<cfreturn news>
</cffunction>
</cfcomponent> -
I am trying to learn CFCs I am working through tutorials in a
book from 2002 called CodeRutters "Discovering CFCs -- ColdFusion
MX Components" by Hal Helms and Benjamin Edwards put out by
Techspedition and I am working a tutorial in a chapter about
inheritance.
The point is to pass arguments using two different classes:
5Employee and 5Person (I put the 5 in front to find the files
easily in my directory) here is the code
5Person.cfc:
<cfcomponent>
<cffunction name="new">
<cfargument name="firstName" required="no" type="string"
default="null">
<cfargument name="lastName" required="no" type="string"
default="null">
<cfargument name="yearBorn" required="no" type="string"
default="null">
<cfargument name="subtype" required="no">
<cfset this.firstName = arguments.firstName>
<cfset this.lastName = arguments.lastName>
<cfset this.yearBorn = arguments.yearBorn>
<cfif IsDefined('arguments.subType')>
<cfset child = arguments.subType>
<cfset StructAppend(child,this,'yes')>
<cfreturn child>
</cfif>
</cffunction>
<cffunction name="getName">
<cfreturn this.firstName + ' ' + this.lastName>
</cffunction>
<cffunction name="setName">
<cfargument name="firstName" required="yes"
type="string">
<cfargument name="lastName" required="yes"
type="string">
<cfset this.firstName = arguments.firstName>
<cfset this.lastName = agruments.lastName>
</cffunction>
</cfcomponent>
5Employee.cfc
<cfcomponent hint="I am an Employee"
extends="com.techspedition.CFCs.5Person">
<cffunction name="new">
<cfargument name="firstName" type="string"
required="no">
<cfargument name="lastName" type="string"
required="no">
<cfargument name="gender" type="string" required="no">
<cfargument name="dateOfBirth" type="string"
required="no">
<cfargument name="department" type="string"
required="yes">
<cfargument name="dateOfHire" type="string"
required="yes">
<cfargument name="subtype" required="no">
<cfinvoke
component="com.techspedition.CFCs.5Person"
method="new"
subtype="#this#"
returnvariable="aPerson"
firstName="#arguments.firstName#"
lastName="#arguments.lastName#"
gender="#arguments.gender#"
dateOfBirth="#arguments.dateOfBirth#">
<cfset this = aPerson>
<cfset this.employeeID = CreateUUID()>
<cfset this.dateOfHire = arguments.dateOfHire>
<cfset this.department = arguments.department>
<cfif IsDefined('arguments.subType')>
<cfset child = arguments.subType>
<cfset StructAppend(child,this,'yes')>
<cfreturn child>
</cfif>
</cffunction>
</cfcomponent>
5testEmployee.cfm
<cfset maxie = CreateObject('component', '5Employee')>
<cfset maxie.new('Maxie', 'Mumm', 'Female', '5/31/1958',
'Accounting', '12/25/1999')>
<cfdump var="#maxie#">
Here is the output:
DEPARTMENT Accounting
YEARBORN null
FIRSTNAME Maxie
LASTNAME Mumm
EMPLOYEEID 6A8A1E0E-C6C9-9A59-B1D1970F03202050
DATEOFHIRE 12/25/1999
gender and dateOfBirth disappear into oblivion. Those to
variables are only defined in 5Employee.cfc and they are lost in
the dump....well his output in the book shows that they make it
along with everything else...well I had a hunch and I changed the
code in 5Employee.cfc:
<cfinvoke
component="com.techspedition.CFCs.5Person"
method="new"
subtype="#this#"
returnvariable="aPerson"
firstName="#arguments.firstName#"
lastName="#arguments.lastName#">
<cfset this = aPerson>
<cfset this.employeeID = CreateUUID()>
<cfset this.gender = arguments.gender>
<cfset this.dateOfBirth = arguments.dateOfBirth>
<cfset this.dateOfHire = arguments.dateOfHire>
<cfset this.department = arguments.department>
this worked. OK WHY is my question, my way makes more sense
because essentially we are invoking the 'super class' 5Person.cfc
and those variables are not included in 5Person, they are in
5Employee...but in the book, the way he did it, he included gender
and dateOfBirth in the invoke statement and it worked...why? Have
CFCs changed since 2002, if so what would be a better book I could
use?Yes, CFC's and the recommendations have changed since then. I
don't know of a good CFC book but I would start by reviewing these
articles paying special attention to:
- Usage of an
init() function
- Usage of the "super" keyword for extended components
- Usage of "variables" scope for storing instance data
- Difference between the "this" scope and the "variables"
scope
- Usage of keyword "VAR" for local function variables
- Usage of "returnType" attribute
http://www.oreillynet.com/pub/a/javascript/2003/09/24/coldfusion_tips.html
http://livedocs.adobe.com/wtg/public/coding_standards/contents.html
http://livedocs.adobe.com/coldfusion/7/htmldocs/00001022.htm -
How to create/call dynamic XML feed from CFC - HELP PLEASE!!
Hi All,
First off I'm a newb to web services. I'm trying to create the invoke a web service on a CFC for a XML feed. When I call the CFC directly all looks fine and is correctly formatted etc:
http://www.prevu.tv/cfc/xyzTest.cfc?method=listPlant
Am I correct in outputting it in this way? What if I output as a string instead......would others be able to consume it?
When I try to invoke it as a web service I am getting an error I do not understand. I am trying to call it using (user/pass not required in CFC):
<cfinvoke webservice="test" method="listPlant" returnvariable="foo">
<cfinvokeargument name="username" value="abc">
<cfinvokeargument name="password" value="123">
</cfinvoke>
<cfoutput><cfdump var="#foo#"></cfoutput>
Here is my CFC code:
<cfcomponent>
<cffunction name="listPlant" access="remote" returntype="xml" output="no">
<cfargument name="username" type="string" required="no">
<cfargument name="password" type="string" required="no">
<cfquery datasource="#request.dsn#" name="getPlant">
SELECT *
FROM plant
INNER JOIN plantaddress ON plant.plantID = plantaddress.plantID
WHERE icePlantID IS NULL
AND categoryID NOT IN (9,10,11)
AND statusID = 1
AND activePlantList = 1
ORDER BY plant.plantID LIMIT 5
</cfquery>
<!---Convert Query to xml--->
<cfprocessingdirective suppresswhitespace="Yes">
<cfcontent type="text/xml; charset=utf-8">
<cfxml variable="xmlobject">
<PrevuPlant>
<cfoutput query="getPlant">
<Plant>
<PlantID>#plantID#</PlantID>
<PlantName>#XmlFormat(plantName)#</PlantName>
<Street>#XmlFormat(street)#</Street>
<Suburb>#XmlFormat(suburb)#</Suburb>
<City>#XmlFormat(city)#</City>
<State>#XmlFormat(state)#</State>
<Country>#XmlFormat(country)#</Country>
<PostCode>#XmlFormat(postcode)#</PostCode>
<Latitude>#XmlFormat(latitude)#</Latitude>
<Longitude>#XmlFormat(longitude)#</Longitude>
<CountryCode>#XmlFormat(countryCode)#</CountryCode>
<AreaCode>#XmlFormat(areaCode)#</AreaCode>
<Phone>#XmlFormat(phone)#</Phone>
<Fax>#XmlFormat(fax)#</Fax>
</Plant>
</cfoutput>
</PrevuPlant>
</cfxml>
<!---Convert back to a string--->
<cfset myvar=toString(xmlobject)>
</cfprocessingdirective>
<cfreturn myvar>
</cffunction>
</cfcomponent>
Can anyone please tell me where I am going wrong, or how the output for a XML feed called from a CFC should look in a browser etc?
ThanksHey Dan....thanks for the prompt reply.
I added the wsdl and this is what I get when I call the service from this cfm page: http://www.prevu.tv/xyzTest.cfm
Have never seen output like this. Is this correct?
The web service I'm writing is also for some .net developers so it may be that I need to output as string also - this discussion has not taken place yet. -
Hi, i'm new to Coldfusion, and i'm a little confused in
regards to passing parameters to a function using
<cfinvokeargument>. My question is: Does the name of
parameter in the cfinvokearguments have to be the same name as the
cfargument name that you're passing the value to? Because that
seems to go against the whole "black box" thing i was taught. And
is there a way to pass the values without having to have to know
the name of the variables in the function?If you are passing variables to the function then yes the
names need to be the same. There are ways around this which goes to
your second question about passing variables without knowing the
name. (see
http://livedocs.macromedia.com/coldfusion/7/htmldocs/wwhelp/wwhimpl/common/html/wwhelp.htm ?context=ColdFusion_Documentation&file=00001056.htm)
As an example I have a document that I want to index and some
indexes will be filled out by the user and some will not so how
would I be able to tell which vars are passed to the
function….So I would loop the Indexes assigned to the
document and check to see if they were passed to the CFC doing
something like this...
EXAMPLE:
<cfquery name="getDocIndexes_rs"
... this is a query to the get the document's indexes ....
</cfquery>
<cfloop query="getDocIndexes_rs">
<!--- check the arguments scope to see if this index var
exist --->
<cfif
isDefined("arguments.Index#getDocIndexes_rs.IndexID#")>
<!--- if defined then get the value ---->
<cfset IndexValue =
arguments["Index"&getDocIndexes_rs.DMIndexID]>
<!--- do something with indexvalue ....... ---->
Ok that was probably a bit much so to simplify this here....
When I sent the variables to the function I did not use the
cfargument to specify the name(s) because I have no idea what they
were at the time.
As an example for yourself pass a variable to a function
using the cfinvokeargument but do not use the cfargument tag. Then
return the variable by doing this.
<!---- THE CFC PAGE (named testreturn.cfc) --->
<cfcomponent>
<cffunction name="myFunction" access="public"
returntype="string">
<cfset myResult= arguments.testvar>
<cfreturn myResult>
</cffunction>
</cfcomponent>
<!---- THE CFM PAGE THAT CALLS THE CFC --->
<cfinvoke component="YourPath.testreturn"
method="myFunction" returnvariable="myResult">
<cfinvokeargument name="testvar" value="HELLO">
</cfinvoke>
<cfoutput>#myResult#</cfoutput>
Hope that wasn’t confusing enough for you...I am tired
so that is my excuse and this is the best I can do at the moment. -
Cfobject / cfinvoke problem in my application.cfc
Hello;
I am trying to use cfobject in my onsessionstart function in my application.cfc file. The cfobject is another application.cfc file I have in a sub directory in the web site, it runs the shopping cart. I am not firing this off properly and I was hoping someone could help me fix my code so it will operate properly.This is my invoke statement:
<cfobject name="SESSION.myShoppingCart" component="ShoppingCart">
<cfinvoke component="#SESSION.myShoppingCart#" method="getShoppingCart">
This is my whole argument statement for on session start:
<cffunction name="onSessionStart" returntype="any" output="true">
<cfset SESSION.created = now()> <!--- This sets off another session in the site --->
<cfobject name="SESSION.myShoppingCart" component="ShoppingCart">
<cfinvoke component="#SESSION.myShoppingCart#" method="getShoppingCart">
</cffunction>
this is my error:
Context validation error for tag cffunction.
The end tag </cffunction> encountered on line 80 at column 11 requires a matching start tag.
The error occurred in C:\website\Application.cfc: line 28
26 : <cffunction name="onSessionStart" returntype="any" output="true">
27 : <cfset SESSION.created = now()>
28 : <cfobject name="SESSION.myShoppingCart" component="ShoppingCart">
29 : <cfinvoke component="#SESSION.myShoppingCart#" method="getShoppingCart">
Can anyone help me? What do I need to do to set off my shopping cart functions on the cfc I am trying to invoke?
Thank You
CFmongerthis is what I am supposed to put in the on sessionstart function:
<cfobject name="SESSION.myShoppingCart" component="ShoppingCart">
But this throws the same error. I am reading this off of instructions from a book. Obviously the book is wrong. Is there a way to make that cfobject statement work? I don't want a return variable. I want the ShoppingCart.cfc that resides in the sub directory /donation/ShoppingCart.cfc to go into client memory, I don't need a return value, I need the shoppong cart application portion fired when they hit the web site, creating a "shopping cart" in session / client variables.
How would I do that using this tag? Thanks.
CFmonger -
Using CFCs statically without cfinvoke
We have a set of CFCs that we use as an application API.
Currently, the way I use them is by instantiating them in the
application scope and then creating aliases (for shortened syntax)
like this:
<cfobject name="Application.Company"
component="components.company">
<cfset $Company = Application.Company>
and then in the application, I call methods like this:
<cfset qCompany = $Company.GetCompanyDetails(cmpid)>
-- All of the objects are intented to be used statically and
have no instance data, but to use them like this, I've obviously
having to create an instance (using CreateObject or cfobject).
-- The reason I don't use CFInvoke to call methods statically
is because I think that it makes the code much more difficult to
read.
-- The one concern I have of using the objects in the way
that I am (by creating instances of them and putting those
instances into application scope) is that if I forget to "var" any
variables in a method, then I have just created "instance data" on
the object, and things could get really tough to debug when
unexpected behavior starts occurring in the application.
-- I 'm trying to find a solution to reference my CFCs, and
then access them later statically without creating an instance at
all. Has anyone ever come up with a solution for this?
-- As a "last resort", I could always create the objects in
Request scope, but there's obviously some performance overhead
there.
Any thoughts on this?On Tue, 30 May 2006 15:23:08 +0000 (UTC), Fernis wrote:
> I think <cfinvoke> is just what you should use.
There's a rather large performance hit when
creating/destroying CFC
instances (one IS still created when doing a
<cfinvoke>, it's just "killed"
immediately after use).
If your CFCs are just "bags o' functions" rather than being
used to define
"objects", it might be an idea to forgo using CFCs, and just
use UDFs (or
libraries of UDFs, as appropriate).
Adam -
How can I use cfc query result to grid.dataprovider
In rich from ,I builder a button , when it click ,I want to
use cfc query some sql result ,and put it in grid.
I use flower code ,but it have error ,help me !!!
<CFSAVECONTENT variable="upd_query">
<cfinvoke
component="test.components.Getorder"
method="GetAllorder"
returnvariable="GetAllorderRet">
</cfinvoke>
<cfif Isstruct(GetAllorderRet)>
s_ghid1.visible= false;
abc.text = "The GetallorderRet is struct";
</cfif>
<cfoutput>
listorder.dataProvider = [#GetAllorderRet.];
</cfoutput>
</CFSAVECONTENT>
In form:
<cfinput type="button" name="s_search" style="
borderThickness:1;" onClick="#upd_query#"
value="Search"/>Can you expand on that? I'm sorry but I am new and a novice to the SSIS world and I want to do this as best I can and as efficiently as I can. Are you saying that Rajen's way suggested above is the way to go?
A little background....external data from a 3rd party client. I'v staged that external data to a SQL Server staging table. I have to try and match that data up to our database using SSN, DOB, and Gender...and if I can't match that way then I have to try
and match by Name. I need to make sure that there is only one and only one account for that match. If I cannot match and match one and only one, then I'll create rows on a DataAnomaly Table. If I do match, then I have to check and make sure that there is only
one and only one Member span for that match. Similarly handle the data anomaly and then check and make sure there is a "Diabetes" claim and similarly handle the DataAnomaly accordingly.
That's where I'm at. Sooooo are you saying to use Rajen's suggestion? I don't think I can do that because I need multiple SQL tasks and I cannot connect multiple OLE DB Source tasks.
Any help and suggestions are greatly appreciated.
Thanks. -
Hi,
In a web application, if I need to call a CFC method from a different CFC, what would be considered as the best way of doing it?
For example, let's say I have two components: Customer and Product. From a method functionA in Customer, I would like to call functionB in Product. I can do one of the following, but which way is best practice and why?
1. Create a Product object in functionA, and use it to call functionB
<cfcomponent name="Customer">
<cffunction name="functionA">
<cfset productObj = createObject('component', 'Product')>
<cfset productObj.functionB()>
</cffunction>
</cfcomponent>
2. Pass a Product object when we initialize a Customer object, and use that to call functionB
<cfcomponent name="Customer">
<cffunction name="init">
<cfargument name="productObj">
<cfset variables.productObj = arguments.productObj>
</cffunction>
<cffunction name="functionA">
<cfset variables.productObj.functionB()>
</cffunction>
</cfcomponent>
3. Assume that Customer object has access to the Product object in the application scope
<cfcomponent name="Customer">
<cffunction name="functionA">
<cfset application.productObj.functionB()>
</cffunction>
</cfcomponent>
Thank you very much.The first two are fine. If the CFC being called is always gonna be the exact same one, then there's no prob directly referencing it in the calling CFC. If the CFC could vary, then pass it in.
If you're only using the CFC transiently, then you could use <cfinvoke> as well in this case.
Directly accessing an application-scoped CFC within a method is poor practice.
Adam -
How to pass a variable into a cfc?
prior to calling the cfinvoke, I have coding that determins a
variable "X"
I need to pass X into a cfc so it can complete the query held
there.
So I tried
<cfinvoke component="A"
method="AList"
returnvariable="AResults">
<cfinvokeargument name="x" value="#X#"
/></cfinvoke>
correct so far?
Now over on the cfc page is where I'm getting stuck
Inside my cffunction I'm adding <cfargument name="X" />
But how do I get the value in?I don't quite understand your question. Can you rephrase?
But before all that, bear in mind that one doesn't pass a
variables into a
*CFC*, one passes it into a function within the CFC. And as
with all
functions, one passes values into the function by passing it
as an
argument. But - of course - the function has to be coded to
expect the
argument.
Your own sample code demonstrates this in action:
<cfinvokeargument name="abbrCode"
value="#companyAbbrCode#" />
(NB: lose the trailing slash: this is CFML, not XML).
So you know how to do that.
Hence me not quite understanding what you're actually asking.
Adam -
Error Invoking CFC... but it's there! I see it!
Greetings all -
I'm hoping someone can help explain why this following attempt at binding a CFC is not working:
1. I set up a CF Server Mapping to my cfc folder:
Logical path = /testcfc
Physical path = E:\ColdFusion8\Components\testcfc
2. I set up a virtual directory to my cfc folder:
Virtual path: /testcfc
Physical path: E:\ColdFusion8\Components\testcfc
3. If I use CFINVOKE to call the CFC, it works as expected.
<cfinvoke component="testcfc.testRequests" method="get_Clients" returnvariable="var">
<cfinvokeargument name="fiscal_year" value="#year(now())#">
</cfinvoke>
<cfdump var="#var#">
4. If I attempt to bind the CFC, I get the error "Error Invoke CFC /testResults.cfc: Not Found"
<cfselect name="tstClientID" id="tstClientID" bind="cfc:testcfc.tstRequests.get_Clients('#year(now())#')" bindonload="true" value="client_id" display="client_name" />
Debugging the error, I see that CF is attempting to find the CFC in the root directory of the app... it is disregarding the directory path ("testcfc") specified entirely. Why??
The bizarre thing is, I've set up the same structure on my PC/dev environment, and it works fine.
How can I further debug this issue? It's got to be a mapping problem, but can;t see what I've done wrong. Any help truly appreciated!
DougI recently stumbled upon this post:
http://www.codersrevolution.com/index.cfm/2008/9/10/ColdFusion-CFC-Binding-Ajax-Proxy-and- Updater-1#comments
Sure enough, my prod environment is running 8.0.0. I'm going to apply to apply the patch to 8.0.1 and see if that corrects the issue. I hope.
Doug -
I am getting a bit confused with cfcs using cfreturn and
cfinvoke please be patient!
1.Setting variables in cfc
In this example cfc I make a query. The cfreturn tag does
<cfreturn expression /> as I understand it. I don´t
understand how you define the expression - can you return
arguments, any column I like in variables? How do I do that?
<cfcomponent><cffunction><cfargument
name="user">
<cfquery name="checkuser">
select col1, col2, col3, col4, col5, col6
from user
where .....=....
</cfquery>
<cfreturn checkuser.col1>
2. Calling cfc:
In cfinvoke you call a variable using returnvariable="". Is
it true that the variable doesn´t have to have the same name
as in the method that the cfinvoke tag is calling? What does return
variable call? How do I define what it calls?In any cffunction, inside or outside a cfc, if you are going
to return a value, you use the cfreturn tag. You can return
constants like true, 1, "Dan is so smart", or variables. What you
return has to be consistent with the returntype attribute of your
cffunction tag.
When you invoke a variable, you can use any name you want as
the return variable. In theory, you don't even know any variable
names inside the function. The return variable does not call
anything. It accepts what the function returns.
It is the cfinvoke tag that calls something. You control what
it calls with it's attributes.
Further details are in the cfml reference manual. -
Calling a Function from another Function within CFC
Hi all,
I have many functions in my CFC that do various things, but
one query is a query that selects absolutely every record from a
table.
The thing is, I need to do a query like this in another
function to obtain only a recordcount of the same table used in
both separate functions. Instead of writing the query out again,
how can I utilise the function already written?
My question is, how can I invoke and use the results of a
query in one cffunction for another cffunction in the same CFC
component?
An example may look like the code attached...
Many thanks for your patience and help!
Mikey.quote:
Originally posted by:
Dan Bracuk
Generally, to call a function from within a cfc, you do
exactly what you do outside a cfc.
For your specific case, if your requirements permit it, you
might consider caching the big query for a couple of seconds. Then
you can continously call the function and not have to wait for it
to run and bring back the data each time.
Do you mean to say that within a CFC function I can execute
the same cfinvoke tags I use in normal CFM pages?
Mikey. -
I would to run a query once that returns a record set and pass that as reference data to functions in a ColdFusion component. Inside those functions, I'd take the query and run a query of queries for aggregate results among other things. Can this be done? I am getting an error basically saying the passed-in query is not a simple value where I use it in the FROM clause of the query.
It works fine when both queries are within the same function, but it's needless overhead to continually get the same ref data.
Example:
template.cfm
<cfobject name="lib" component="mycfc">
<cfinvoke component="#lib#" method="getQueryRefData" returnvariable="refData" />
<cfinvoke component="#lib#" method="getSum" returnvariable="sum" refdata="#refData#" />
mycfc.cfc
<cffunction name="getQueryRefData" access="public" returntype="query">
<cfquery name="allData" datasource="myDatasource">
SELECT * FROM answer
</cfquery>
<cfreturn allData>
</cffunction>
<cffunction name="getSum" access="public" returntype="numeric">
<cfargument name="refData" type="query" required="yes">
<cfquery name="deptSum" dbtype="query">
SELECT COUNT(*) AS total, department
FROM ARGUMENTS.refData <--- ERROR occurs here --->
GROUP BY department
</cfquery>
<cfreturn Val(deptSum.total)>
</cffunction>This works when I run it.
<cffunction name="q_of_q" returntype="query">
<cfargument name="QueryIn" type="query">
<cfquery name="QueryOut" dbtype="query">
select count(*) thecount
from arguments.queryin
</cfquery>
<cfreturn QueryOut>
</cffunction>
<cfquery name="x" datasource="burns">
select 1 f1 from dual
</cfquery>
<cfset abc = q_of_q(Queryin = x)>
<cfdump var="#abc#" label="abc">
Try it and if it works, start modifying it until it either does what you want it to do, or crashes. -
Problem passing values to cfc component
I have a cfc component with methods to insert, retrieve and
update a record in a table. There are several forms associated with
the component, each which handles a subset of the fields in the
table. The update method is called with arguments that identify
which subset of fields is to be modified and the values for those
fields.
The forms typically have a couple of radio button groups and
a couple of lists, most of which allow multiple selections. I want
to create a variable for each radio button group and each list. The
variables give the button selected (for the buttons) and a string
of the values selected (for the lists). These are to be passed as
arguments to the update method.
I can construct the variables using standard Java script
statements (if, for,etc.). But if I do, CFINVOKEARGUMENT doesn't
recognize them. The same thing happens if I try to use CFQUERY
directly. I get a message like "variable is undefined". If I try to
set the values using CFSET statements, it doesn't recognize the
form fields. It says the field is not an element of the form.
So I can look at the form fields to create a variable but
then the variable can't be used by the update method. Or I can
create an argument that can be passed to update, but it doesn't
know anything about the form values. I've tried all variations I
can think of with and without #'s and single & double quotation
marks.
Suggestions would be appreciated.See in line comments.
waz69 wrote:
> Sorry for the delayed response...I was pulled away right
after I posted my
> problem. Here are extracts from the code. I've only
included the sections
> that deal with updating the table.
>
> In the CFC file:
>
> <cffunction access="public" name="SaveFormValues"
output="false"
> returntype="boolean">
> <cfargument name="Screen" type="string"
required="yes">
> <cfargument name="Arg1" type="string"
required="yes">
> <cfargument name="Arg2" type="string"
required="yes">
> <cfargument name="Arg3" type="string"
required="yes">
> <cfargument name="Arg4" type="string"
required="no">
> <cfargument name="Arg5" type="string"
required="no">
> <cfargument name="Arg6" type="string"
required="no">
> <cfset var isSuccessful=true>
> <cftry>
> <cfquery name="SaveValues" datasource="FPDS
Sample">
> UPDATE Report_specs SET
> <cfif arguments.Screen EQ "Scope">
> ReportOn = '#arguments.Arg1#',
> SubtotalGroup = '#arguments.Arg2#',
> Projects = '#arguments.Arg3#',
> Sites = '#arguments.Arg4#'
> </cfif>
> <cfif arguments.Screen EQ "Criteria"> (,,code goes
here for next set of
> fields...) </cfif>
> <cfif arguments.Screen EQ "Table"> (,,code goes
here for next set of
> fields...) </cfif>
> <cfif arguments.Screen EQ "Chart"> (,,code goes
here for next set of
> fields...) </cfif>
> <cfif arguments.Screen EQ "Detail"> (,,code goes
here for next set of
> fields...) </cfif>
> WHERE Report_specs.rid = #Session.FPRU_rid#
> </cfquery>
> <cfcatch type="Database"><cfset
isSuccessful=false></cfcatch>
> </cftry>
> <cfreturn isSuccessful />
> </cffunction>
>
> In the CFM file:
>
> <head>
> <script language="JavaScript">
>
> function SaveValues(frm) {
> var RptOn="", SubGrp="", SL="", PL="" ;
> for(var i=0; i<3; i++)
> {if(frm.ReportOn
.checked) RptOn = frm.ReportOn.value ;
> if(frm.SubtotalGroup
.checked) SubGrp = frm.SubtotalGroup.value ; } ;
> for(i = 0; i < frm.Projects.options.length; i++)
> {if(frm.Projects.options
.selected ) PL = PL + ', ' +
> frm.Projects.options.value ; } ;
> for(i = 0; i < frm.Sites.options.length; i++)
> {if(frm.Sites.options
.selected ) SL = SL + ', ' +
> frm.Sites.options.value ; } ;
>
> ...(This is the section where I'm having problems. I
have the values I want
> to pass the variables just defined.
> But I can't get them into the CFINVOKEARGUMENT
statements below. I've
> tried variations of #'s, CFSETS, etc.)...
>
> <cfobject component="RecordAccess"
name="SaveValues">
> <cfinvoke component="#SaveValues#"
method="SaveFormValues" >
> <cfinvokeargument name="Screen" value="Scope">
> <cfinvokeargument name="Arg1" value="RptOn">
> <cfinvokeargument name="Arg2" value="SubGrpr">
> <cfinvokeargument name="Arg3" value="PL">
> <cfinvokeargument name="Arg4" value="SL">
> </cfinvoke>
> }
>
> </script>
> </head>
This is never going to work. JavaScript is executed on the
client's
computer in the browser. It is no idea of what is CFC is or
how to
access one. The cfc lives on the server, it can only exist
and run
while the http request is being built by the CF engine.
>
> <body onFocus="GetValues(this.form)" >
>
> <form action="" method="post" name="ScopeDetail"
id="ScopeDetail">
> <table width="85%" border="0" cellspacing="2"
cellpadding="2">
> <tr>
>
> ...(various buttons)...
>
> <td width="8%"><input name="SaveForm"
type="button" id="SaveForm"
> onclick="SaveValues(this.form)"
value="Save"></td>
>
> ...(other buttons)...
>
> </table>
>
> <table width="96%" border="0" cellspacing="2"
cellpadding="2">
> <tr>
> ...(column headers)...
> </tr>
>
> <tr>
> <td rowspan="3" align="right"
valign="top"> </td>
> <td height="110" colspan="2" align="right"
valign="top"><div
> align="left">
> <p>
> <label> <input name="ReportOn" type="radio"
value="Users" checked>
> Unique users</label>
> <br>
> <label> <input type="radio" name="ReportOn"
value="AllVisits"> All
> visits</label>
> <br>
> <label> <input name="ReportOn" type="radio"
value="LastVisit"> Last visit
> only</label>
> <br>
> </p>
> </div></td>
> <td rowspan="3" valign="top"> </td>
> <td colspan="3" rowspan="3"
valign="top"><p><select name="Projects"
> size="10" multiple id="Projects"
onChange="getSites(this.form)"><cfoutput
> query="ProjectList">
> <option
>
value="#ProjectList.projectid#">#ProjectList.projectname#</option>
> </cfoutput></select></p></td>
> <td width="3%" rowspan="3"
valign="top"> </td>
> <td width="34%" rowspan="3"
valign="top"><select name="Sites" size="15"
> multiple id="Sites">
> <option> ---------------------------------------
</option>
> </select></td>
> <tr>
> <td height="23" colspan="2" align="right"
valign="top"><div align="left">
> <h3>Show Summaries of </h3>
> </div></td>
> <tr>
> <td height="100" colspan="2" align="right"
valign="top"><div
> align="left">
> <label> <input name="SubtotalGroup"
type="radio" value="Both" checked>
> Project & Sites</label>
> <br>
> <label> <input type="radio"
name="SubtotalGroup" value="Projects">
> Projects only</label>
> <br>
> <label> <input type="radio"
name="SubtotalGroup"
> value="Sites"> Sites only</label>
> </div></td>
>
> </table>
> </form>
> </body>
waz69 wrote:
> I tried creating hidden fields to which I assign my
desired values. The
> CFINVOKEARGUMENTs then become:
>
> <cfinvokeargument name="Arg1" value=frm.Hide1>
> <cfinvokeargument name="Arg2" value=frm.Hide2>
> etc.
>
> What ends up in the table is the name of the field
(frm.Hide1) not
the value
> of the field. I've also tried with with quotes (single
and double)
which give
> the same result and with #'s which gives me an error
about undefined
element.
>
This is what your are going to need to do. But the javascript
form
object no longer exists once the request has been sent to the
server.
After that you are dealing with the "form" structure. So your
arguments
are going to look something like.
<cfinvokeargument name="Arg1" value="#form.Hide1#">
OR interchangeably
<cfinvokeargument name="Arg2" value="#form['Hide2']#">
When blending JavaScript and ColdFusion, one must be
constantly aware of
the order of actions. JavaScript can only run and exist on
the client,
it has no direct knowledge of any ColdFusion variables or
logic.
Vice-a-versa, ColdFusion only runs and exists on the server.
It has no
direct knowledge of the Client or its state.
To blend the two you have to carefully pass any required,
shared
information from one location to the other.
Maybe you are looking for
-
How to set multiple styles on a single component in flex ?
Hi , I would like to know how to set multiple styles on a single component in flex. Can anyone give me an example as to how to set multiple styles for a single component ? Thanks , Regards, Ajantha
-
ASM like RAID 1 between two storages
In my production environment instances of Oracle are under the file system JFS2. Soon we will have to relocate space for these file or switch to ASM. Our preference is going to the ASM, but we do need some tests we are conducting. Today, in a product
-
Handling events/delegates within TestStand
Has anyone got any experience of handling delegates or events within from a C# assembly? My application issues an event to inform that a time consuming operation has completed its running. I would like TestStand to handle the event directly and trig
-
Hi, I have a problem with gcc. In my laptop I had gcc4 installed, with libstdc++ and glibc, and everything worked smoothly. I had the necessity to install gcc-3.4 to compile an old version of a data analysis program which was not ported to gcc4. I in
-
I am trying to send an email with a photo attached and it will not send. The file goes to the out box but no further. It prevents me from sending other emails until it is deleted. After a while it gives the error message to consult your provider.The