Skip to Content

How to Invoke CFC Methods with CFML

In this tutorial, we'll learn the basics of creating and working with CFCs in CFML, their importance, and code examples so you can get started with your own custom functions quickly.

What Are CFCs?

CFCs (ColdFusion Components) are a great demonstration of the true power behind CFML and a way to separate your application logic from your interface. They're especially useful for creating reusable bits of code that you can utilize and invoke throughout your application.

CFCs use the .cfc file extension to help differentiate from a regular .cfm script file.

Tags for Creating CFCs

We'll explore three different tags associated while creating our CFC:

  • cfcomponent - Defines the component and includes specific attributes for introspection.
  • cffunction - Defines a component method, or function, that you can invoke from other CFCs or CFML files.
  • cfargument - Defines a custom argument, or parameter, for each function.

CFC Code Example

Let's create our first CFC and walk through its structure and each of its features. Create a file called Data.cfc and copy/paste the following code:

<cfcomponent displayName="myComp" output="false">

<cffunction name="myFunc" returnType="query" output="false">
<cfargument name="id" type="numeric" required="true">
<cfset var qryData = "">

<cfquery name="qryData" datasource="myDatasource">
SELECT *
FROM myTable
WHERE id = <cfqueryparam value="#arguments.id#" cfsqltype="cf_sql_bigint">;
</cfquery>

<cfreturn qryData>
</cffunction>

</cfcomponent>

Every CFC must start with an opening and closing cfcomponent tag. This defines the CFC and creates an association with its included methods. The displayName attribute is used for introspection. The output attribute is an option boolean parameter. In this case, a value of "false" prevents unnecessary page output while processing the function.

Within each component, you can create as many functions as you'd like using the cffunction tag. In this example, we've created a single function called "myFunc" where we'll query a hypothetical database table by returning all columns and their associated values that match a given "id". The returnType specifies the resulting data type expected to be returned from the function call, in this case, our query results. And the optional output parameter with a value of "false" instructions the function to refrain from returning text, including whitespace, in the result.

Within the function, you can create as many arguments as you'd like using the cfargument tag. In this case, a numeric ID variable is required to continue processing the remainder of the function call. If the ID variable is not passed in, an error will be thrown.

Next, we have a local variable qryData prefixed with the var keyword, indicating that this variable can only be used inside the function where it's declared. This is important and best practice to prevent accidental variable rewriting within other CFC methods.

Finally, we use the cfquery tag to execute our SQL call and return the resultset from the query.

Invoking CFC Methods

To invoke our CFC methods, retrieve the return data, and output the resultset to the screen, we'll explore a few different options.

The cfinvoke tag

The first method is with the cfinvoke tag. Here, we'll invoke a function call to our newly created component and method, and assign a return variable we can use to dump the data:

<cfinvoke component="myComp" method="myFunc" returnVariable="qryData">
<cfdump var="#qryData#">

The cfobject tag

The second method is with the cfobject tag. Similar to the first, we invoke our newly created component method, but instead, we create an instance of the component that we can reuse without redefining it each time. This can significantly improve processing time where you're making multiple component calls in a single page request:

<cfobject name="objComp" component="myComp">

<cfset qryData = objComp.myFunc(id = 1)>
<cfdump var="#qryData#">

<cfset qryData = objComp.myFunc(id = 2)>
<cfdump var="#qryData#">

The CreateObject() function

The third method is very similar to the previous method, except we use the CreateObject() function to create an instance of our component and associated methods instead of a tag.

<cfset objComp = CreateObject("component", "myComp")>

<cfset qryData = objComp.myFunc(id = 1)>
<cfdump var="#qryData#">

<cfset qryData = objComp.myFunc(id = 2)>
<cfdump var="#qryData#">

The CreateObject() method is my preferred way of defining objects in CFML due to the flexibility it allows. Here, you're passing in two arguments to the function call. The first argument is the type of object we're creating an instance for, in this case, a component. The second argument is the name of the component, "myComp".

The one thing I'd like to note about passing in a component name is the location of the CFC file. Passing in "myComp" assumes that the component is in the same folder as the script executing the code. However, if the component file were located in a sub-directory, you would use dot notation to separate each directory name to its location:

<cfset objComp = CreateObject("component", "path.to.myComp")>

Conclusion

That's it! Components in real-world applications can be a lot more complex than this, but this basic structure should get you going in the right direction.

Created: July 16, 2023