Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Object-Oriented Programming in ColdFusion
Object-Oriented Programming in ColdFusion

Object-Oriented Programming in ColdFusion: Break free from procedural programming and learn how to optimize your applications and enhance your skills using objects and design patterns

eBook
$9.99 $25.99
Paperback
$43.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Object-Oriented Programming in ColdFusion

Chapter 1. Introducing ColdFusion Components

ColdFusion Components, commonly known as CFCs, were introduced in ColdFusion MX. In essence, they are simple templates written in existing CFML tags and CFScript. As such, they are not complex, confusing, or difficult to understand. If you can code CFML, you can create CFCs.

In this chapter, we will cover the following:

  • The basic structure of a ColdFusion component

  • The component tags, functions, and methods

  • Passing parameters using the argument scope

For those with any experience with ColdFusion, components should be relatively commonplace. Object-Oriented Programming (OOP) relies heavily on the use of ColdFusion components, so before proceeding onto the ins and outs of OOP, let's re-familiarize ourselves with components within ColdFusion. This introduction will also serve as a reference when looking at subjects later in the book.

ColdFusion Components use the same ColdFusion Markup Language (CFML) as 'standard' ColdFusion pages. The core difference is the file extension components must be saved with a .cfc file extension as opposed to the .cfm file extensions for template pages.

The basic structure of a ColdFusion Component is:

  • The component (the page within which you create the code to hold data or perform functions)

  • The methods available to run within the CFC, also known as functions

In simple terms, CFCs themselves form a framework within ColdFusion, allowing you to write structured, clear, and organized code. They make application development easier to manage, control, and maintain.

Note

ColdFusion Components use the same CFML as 'standard' ColdFusion pages. The core difference is the file extension.

Why use CFCs?

It is not unusual for applications to grow and seem overly complex. Pages containing detailed information, such as business logic, data access and manipulation, data validation, and layout/presentation logic, can become untidy and hard to manage.

Creating and developing applications using CFCs enables you to separate the code logic from the design and presentation, and build an application based around, if not using, traditional Model View Controller (MVC) framework methodologies.

Utilizing CFCs and creating a clear structured format for your code will help reduce the complexity of logic within your pages and improve the application speed. Having a clearly structured, well organized code base will make it easier to develop as an individual and share resources within a team. This is the instant benefit of CFC development.

A well-written CFC will allow you to reuse your functions, or methods, across your entire application, helping to reduce the risk of code duplication. It will keep your component libraries and code base to a more easily manageable size, preventing it from becoming convoluted and difficult to follow.

ColdFusion components are an incredibly powerful and valuable means of creating efficient code. They allow you to:

  • Share properties and variables between other methods and functions

  • Share and interact with functions contained within other CFCs

  • Inherit the properties and methods of a base component

  • Overwrite methods and functions within other components

CFCs also give you the ability to clearly document and comment your code, letting you and other developers know what each function and property should do, what it should be expecting to receive to do the job and what output it will give you. ColdFusion components are able to read themselves and display this data to you, using a form of introspection, which we will cover in Chapter 2.

Although CFCs are an effective tool for code reuse, this is not to say they should be used for every reusable function within your application. They are not a complete replacement for custom tags and user-defined functions.

When you load a CFC (instantiate the component), this uses up more processing time than it would to call a custom tag or a User-Defined Function (UDF) into use. Once a CFC has been instantiated, however, calling a method or function within the component will take approximately the same time as it would to call a UDF.

It is important, therefore, that CFCs should not necessarily be used as a complete replacement for any UDFs or custom tags that you have in your application. Any code you write can, of course, be optimized, and changes can be made as you learn new things, but UDFs and custom tags perform perfectly well. Using them as they are will help to keep any processing overheads on your application to a minimum.

Grouping your functions

You may have already written custom tags and user-defined functions that allow similar functionality and reusability, for example, a series of UDFs that interact with a shopping cart. By grouping your functions within specific components according to their use and purpose, you can successfully keep your code library organized and more efficient.

You can also further clean your code library by compiling or grouping multiple related components into a package, clearly named and stored in a directory within your application.

Organizing your components

A typical method for organizing your CFC library is to create a directory structure based on your company or domain name, followed by a directory whose name references the purpose of the included components, for example, 'com.coldfumonkeh.projecttracker' in the webroot of your application.

Within this directory, you would then create a directory for each group (or package), of components, with a name reflecting or matching the component name and purpose.

Use your ColdFusion Components to create a component structure, or a library, that contains grouped methods and functions, particularly if the methods share properties or data.

Why use CFCs?


It is not unusual for applications to grow and seem overly complex. Pages containing detailed information, such as business logic, data access and manipulation, data validation, and layout/presentation logic, can become untidy and hard to manage.

Creating and developing applications using CFCs enables you to separate the code logic from the design and presentation, and build an application based around, if not using, traditional Model View Controller (MVC) framework methodologies.

Utilizing CFCs and creating a clear structured format for your code will help reduce the complexity of logic within your pages and improve the application speed. Having a clearly structured, well organized code base will make it easier to develop as an individual and share resources within a team. This is the instant benefit of CFC development.

A well-written CFC will allow you to reuse your functions, or methods, across your entire application, helping to reduce the risk of code duplication. It will keep your component libraries and code base to a more easily manageable size, preventing it from becoming convoluted and difficult to follow.

ColdFusion components are an incredibly powerful and valuable means of creating efficient code. They allow you to:

  • Share properties and variables between other methods and functions

  • Share and interact with functions contained within other CFCs

  • Inherit the properties and methods of a base component

  • Overwrite methods and functions within other components

CFCs also give you the ability to clearly document and comment your code, letting you and other developers know what each function and property should do, what it should be expecting to receive to do the job and what output it will give you. ColdFusion components are able to read themselves and display this data to you, using a form of introspection, which we will cover in Chapter 2.

Although CFCs are an effective tool for code reuse, this is not to say they should be used for every reusable function within your application. They are not a complete replacement for custom tags and user-defined functions.

When you load a CFC (instantiate the component), this uses up more processing time than it would to call a custom tag or a User-Defined Function (UDF) into use. Once a CFC has been instantiated, however, calling a method or function within the component will take approximately the same time as it would to call a UDF.

It is important, therefore, that CFCs should not necessarily be used as a complete replacement for any UDFs or custom tags that you have in your application. Any code you write can, of course, be optimized, and changes can be made as you learn new things, but UDFs and custom tags perform perfectly well. Using them as they are will help to keep any processing overheads on your application to a minimum.

Grouping your functions

You may have already written custom tags and user-defined functions that allow similar functionality and reusability, for example, a series of UDFs that interact with a shopping cart. By grouping your functions within specific components according to their use and purpose, you can successfully keep your code library organized and more efficient.

You can also further clean your code library by compiling or grouping multiple related components into a package, clearly named and stored in a directory within your application.

Organizing your components

A typical method for organizing your CFC library is to create a directory structure based on your company or domain name, followed by a directory whose name references the purpose of the included components, for example, 'com.coldfumonkeh.projecttracker' in the webroot of your application.

Within this directory, you would then create a directory for each group (or package), of components, with a name reflecting or matching the component name and purpose.

Use your ColdFusion Components to create a component structure, or a library, that contains grouped methods and functions, particularly if the methods share properties or data.

The ColdFusion component tags


You can use these following tags to create a ColdFusion Component.

Tag

Purpose

cfcomponent

The core CFC tag that defines the component structure. All other content in the component is wrapped within this tag.

cffunction

Creates a method (function) within the component.

cfargument

Creates a parameter, otherwise known as an argument, to be sent to the function.

cfproperty

Can be used to define and document the properties within your component. Can also be used to define variables within a CFC that is used as a web service.

These previously mentioned tags are written within the .cfc file that defines the ColdFusion component.

Note

In the world of object-oriented programming, you will commonly hear or see reference to the word 'Class'. A class is essentially a blueprint that is used to instantiate an object, and typically contains methods and instance variables.

When discussing a Class in the context of ColdFusion development, we are basically referencing a ColdFusion component, so when you see or read about classes, remember it is essentially an alias for a CFC.

Our first component


To get started, in this example, we will create a component and functions to output the message "Hello world".

Create a new file called greetings.cfc and save it within your ColdFusion webroot.

The following is a component base tag; add this code into the new CFC to define the component:

<cfcomponent displayName="greetings">
</cfcomponent>

Listing 1.1 component base tags

As you can see, the name attribute within the CFC matches the name of the file. The cfcomponent tags form the base structure of our ColdFusion Component. No other code can be placed outside of these tags, as it will simply display an error.

It may be helpful to think of the cfcomponent tag as the wrapping paper on a parcel. It forms the outer shell of the package, holding everything else nicely in place.

Defining a method

We have now created the component, but at the moment it does not actually do anything. It has no function to run. We need to add a method into the CFC to create a function to call and use within our application. The following code is a basic function definition; place it between the opening and closing cfcomponent tags:

<cffunction name="sayHello">
<!--- the CFML code for the method will go here --->
</cffunction>

Listing 1.2 basic function definition

You have now added a method to the CFC. The cffunction tags are nested within the cfcomponent tags. We now need to add some CFML code within the cffunction tags to create our method and perform the operation. Let's create a variable within the function that will be our display message. The following code is for declaring a string variable; place it inside the cffunction tags:

<cffunction name="sayHello">
<cfset var strHelloMessage = 'Hello World!' />
</cffunction>

Listing 1.3 declaring a string variable

We have created a string variable containing the text to display to the browser.

Returning the data

To return the data we need to add an extra tag into the method. This is possible by using the cfreturn tag, which returns results from a component method. The cfreturn tag has one required attribute that is the expression or value you wish to return.

Add the following code to your CFC so our method will return the welcome message and the completed component will look like this:

<cfcomponent displayName="greetings">
<cffunction name="sayHello">
<cfset var strHelloMessage = 'Hello World!' />
<cfreturn strHelloMessage />
</cffunction>
</cfcomponent>

Listing 1.4 returning data from the function

ColdFusion 9 scripted components

Since the release of ColdFusion 9, developers now have the ability to also write ColdFusion components in complete script syntax instead of pure tag form.

To write the previous component in this format, the code would look as follows:

component
displayname="greetings"
{
function sayHello(){
// the CFML code for the method will go here
var strHelloMessage='Hello World';
return strHelloMessage;
}
}

Listing 1.5 component declaration in the script syntax

Although written using cfscript syntax, there is no requirement to wrap the code within<cfscript> tags, instead we can write it directly within the .cfc page.

We do not even need to contain the code within cfcomponent tags, as the entire content of the component will be compiled as cfscript if left as plain text without tags.

Creating your object

There it is, a simple ColdFusion Component. The method is created using the cffunction tags, wrapped up nicely within the cfcomponent tags, and the value returned using the cfreturn tag. Now that we have written the function, how do we call it?

In this example, we will call the component and run the method by using the createObject() function. Create a new file called hello.cfm and add the following code to the template:

<cfset objGreeting = createObject('component', 'greetings') />
<cfoutput>#objGreeting.sayHello()#</cfoutput>

Listing 1.6 creating the component object

In the previous code, we have created an instance of the greetings CFC, which we can reference by using the objGreeting variable. We have then accessed the sayHello() method within the component, surrounded by cfoutput tags, to display the returned data.

Save the file and view it within your browser. You should now see the welcome message that we created within the method.

Restricting your functions to scopes


Imagine we are sending some data through to a login page in our application within the URL scope; the first and last name of a particular person. On the page, we want to join the two values and combine them into one string to form the individual's full name. We could write the code directly on the page, as follows:

<cfoutput>
Hello, #URL.firstName# #URL.lastName#
</cfoutput>

Listing 1.7 displaying URL variables as a string

Although this works, you can revise the code and transform it into a ColdFusion function to concatenate the two values into the required single string and return that value:

<cffunction name="getName">
<cfset var strFullName = URL.firstName & ' ' & URL.lastName />
<cfreturn strFullName />
</cffunction>

Listing 1.8 concatenate variables into string

You can then call this function within your .cfm page to output the resulting string from the function:

<cfoutput>
#getName()#
</cfoutput>

However, within this code you have restricted yourself to using only the specific URL scope. What if the first name and last name values were in the FORM scope, or pulled from a query? This block of code is useful only for values within the form scope.

Using arguments within your methods

To allow us to be able to pass in any parameters into the getName() function, we need to use the cfargument tag to send data into the method. By changing the function in the following code example, the method will create the concatenated string and produce the same results from two parameters or arguments that you choose to pass in.

<cffunction name="getName">
<cfargument name="firstName" type="string" />
<cfargument name="lastName" type="string" />
<cfset var strFullName = arguments.firstName & ' ' & arguments.lastName />
<cfreturn strFullName />
</cffunction>

Listing 1.10 using arguments within your function

The cfargument tag creates a parameter definition within the component method, and allows you to send in arguments for inclusion into the functions.

The Arguments scope

The Arguments scope only exists in a method. The scope contains any variables that you have passed into that method, and you can access the variables within the Arguments scope in the following ways:

  • using structure notation - Arguments.variablename or Arguments["variablename"]

  • using array notation - Arguments[1]

Note

The Arguments scope does not persist between calls to available CFC methods, meaning that you cannot access a value within the Arguments scope in one function from inside a different function.

Redefine the function parameters

By defining two arguments and sending in the values for the first and last names, you have created an unrestricted function that is not tied to a specific scope or set of hardcoded values. You can instead choose what values to pass into it on your calling page:

<cfoutput>
#getName('Gary', 'Brown')#
</cfoutput>

Lsiting 1.11a sending parameters into our function

Now that we have removed any restrictions to the values we pass in, and taken away any references to hardcoded variables, we can reuse this function, sending in whichever values or variables we choose to. For example, we could use variables from the FORM scope, URL scope, or query items to concatenate the string:

<cfoutput>
#getName(form.firstName, form.lastName)#
</cfoutput>

Listing 1.11b sending parameters into our function

Let's take our getName() method and add it into the greeting.cfc file. By doing so, we are grouping two methods that have a similarity in purpose into one component. This is good programming practice and will aid in creating manageable and clearly organized code.

Our greeting.cfc should now look like this:

<cfcomponent name="greetings">
<cffunction name="sayHello">
<cfset var strHelloMessage = 'Hello World!' />
<cfreturn strHelloMessage />
</cffunction>
<cffunction name="getName">
<cfargument name="firstName" type="string" />
<cfargument name="lastName" type="string" />
<cfset var strFullName = arguments.firstName & ' ' & arguments.lastName />
<cfreturn strFullName />
</cffunction>
</cfcomponent>

Listing 1.12 revised greeting.cfc

Combining your methods

As we have seen, you can easily access the methods within a defined CFC and output the data in a .cfm template page.

You can also easily access the functionality of one method in a CFC from another method. This is particularly useful when your component definition contains grouped functions that may have a relationship based upon their common purpose.

To show this, let's create a new method that will use the results from both of our existing functions within the greetings.cfc file. Instead of displaying a generic "Hello World" message, we will incorporate the returned data from the getName() method and display a personalized greeting.

Create a new method within the CFC, called personalGreeting.

<cffunction name="personalGreeting">
<cfargument name="firstName" type="string" />
<cfargument name="lastName" type="string" />
<cfscript>
strHello = sayHello();
strFullName = getName(firstName=arguments.firstName, lastName=arguments.lastName);
strHelloMessage = strHello & ' My name is ' & strFullName;
</cfscript>
<cfreturn strHelloMessage />
</cffunction>

Listing 1.13 personalGreeting method

Within this method, we are calling our two previously defined methods. The returned value from the sayHello() method is being stored as a string variable, "strHello".

We then retrieve the returned value from the getName() method and store this in a string variable "strFullName". As we have written the getName() function to accept two arguments to form the concatenated name string, we also need to add the same two arguments to the personalGreeting() method, as done in the previous code. They will then be passed through to the getName() method in exactly the same way as if we were calling that function directly.

Using the two variables that now hold the returned data, we create our strHelloMessage variable, which joins the two values, and is then returned from the method using the cfreturn tag.

In this method, we used CFScript instead of CFML and cfset tags, which were used in our previous functions. There is no hard and fast rule for this. You can use whichever coding method you find the most comfortable.

Let's call this method on our hello.cfm template page, using the following code:

<!--- instatiate the component --->
<cfset objGreeting = createObject('component', 'greetings') />
<!--- access the method and assign results to a string --->
<cfset strPersonalGreeting = objGreeting.personalGreeting( firstName="Gary", lastName="Brown") />
<cfoutput>#strPersonalGreeting#</cfoutput>

Listing 1.14 calling the personalGreeting method

We are sending in the same arguments that we were passing through to the original getName() method, in the same way. This time we are passing these through using the newly created personalGreeting() method.

You should now see a personalized greeting message displayed in your browser:

Protecting your local variables


In our previous personalGreeting() method, we included two separate functions, sayHello() and getName(), into the main method. This is not an uncommon practice, and is what you would expect when writing detailed components with relationships between its included functions.

One issue that can arise when developing in this way is when two or more methods contain a variable of the same name and the value of that variable is accessed or changed by one of the methods.

As an example, the following code contains two functions, baseNumber() and multiplyNumbers().

While the cfcomponent tag has been excluded in this example, this could also easily be turned into a CFC by wrapping the functions within cfcomponent tags.

<cfoutput>
<cffunction name="baseNumber" returnType="numeric">
<cfargument name="a" type="numeric" required="true" />
<cfset x = arguments.a />
<cfreturn x />
</cffunction>
<cffunction name="multiplyNumbers" returntype="string">
<cfargument name="a" type="numeric" required="true" />
<cfargument name="b" type="numeric" required="true" />
<!--- multiply our basenumber value by 10 --->
<cfset x = 10 />
<cfset y = baseNumber(a) />
<cfreturn y & " multiplied by " & x & " = " & x * arguments.b />
</cffunction>
<cfloop from="1" to="10" index="i">
#multiplyNumbers(i,i)#<br />
</cfloop>
</cfoutput>

Listing 1.15 two user-defined functions

A cfloop tag runs a loop from 1 to 10. The multiplyNumbers() function accepts two arguments. In this example, these are both the index numbers of the loop. We want to multiply our baseNumber value (argument 'a'), by 10 for each loop, creating a 10 times table list. To do this, the multiplyNumbers() function has a hardcoded value (x) that is set to the value of 10.

The desired results you would expect from this code should be:

1 multiplied by 10 = 10
2 multiplied by 10 = 20

However, this is not the case. If you save the code to a .cfm template and run it in your browser, you will get the following result:

This is clearly not the result you would expect. So what's happening to cause this issue? Let's take another look at our two functions:

<cffunction name="baseNumber" returnType="numeric">
<cfargument name="a" type="numeric" required="true" />
<cfset x = arguments.a />
<cfreturn x />
</cffunction>
<cffunction name="multiplyNumbers" returntype="string">
<cfargument name="a" type="numeric" required="true" />
<cfargument name="b" type="numeric" required="true" />
<!--- multiply our basenumber value by 10 --->
<cfset x = 10 />
<cfset y = baseNumber(a) />
<cfreturn y & " multiplied by " & x & " = " & x * arguments.b />
</cffunction>

Listing 1.16 examining the two methods

You can see that both functions have a variable called x. The baseNumber() function stores the value of the argument as the x variable, which it returns into the multiplyNumbers() function for use in the equation. The multiplyNumbers() function also has a variable called x, which is the hardcoded number we wish to use as a multiplier, in this case 10.

Within the function, the returned value from the baseNumber() method is assigned to y for use in the equation, but as this included function is run, it overwrites the value of the hardcoded x variable with its own x value. This, in turn, is passed into the equation, which throws off the expected results.

In the previous example, the x value in both functions is public, meaning that it can be altered or overwritten by any included functions, or if in a CFC, any defined method within the component. They are, in essence, set as 'open' variables that can be accessed and amended.

By running the two functions in this way, with openly accessible variables, it has the effect of ruining our ten times table. Imagine that we had a method controlling the shopping cart in an e-commerce application, updating quantities and costs, perhaps even stock levels of products. If we left these public variables open, they could be accessed by any included functions, and the values could change dramatically altering our shopping cart and its data.

Using the Var scope

To avoid this issue, the best practice is to set any local function variables to only be accessed by that particular function. This is achieved by using the Var keyword when setting variables. By applying variable to the Var scope, you are restricting public access to them and declaring that they are only accessible within the method in which they are defined. This removes any chance that external functions will corrupt the values.

Note

You should always use the Var keyword on variables that are used only inside of the function in which they are declared.

Let's alter our code to include the Var keyword to ensure the variables are available only to the functions in which they are written:

<cffunction name="baseNumber" returnType="numeric">
<cfargument name="a" type="numeric" required="true" />
<cfset Var x = arguments.a />
<cfreturn x />
</cffunction>
<cffunction name="multiplyNumbers" returntype="string">
<cfargument name="a" type="numeric" required="true" />
<cfargument name="b" type="numeric" required="true" />
<cfset Var x = 10 />
<cfset var y = baseNumber(a) />
<cfreturn y & " multiplied by " & x & " = " & x * arguments.b />
</cffunction>

Listing 1.17 Var scoping our variables

If we save the code with the Var keyword applied to the variables and view the page in the browser, you will now see the correct results displayed:

Regardless of the type of variable you are using within your component methods, (a query, string, integer, array, or structure) if it is used only within the function in which it is declared, it needs to be Var scoped to protect it and to avoid any unwanted amendments by other functions.

Placing your Var scoped variables

Up to ColdFusion 8, all Var scoped variables were required to be placed after any arguments within the function (if there are any included), and before any CFML.

Enhancements in ColdFusion 9 removed this restriction, and Var scoped variables can be placed anywhere within a code block or function.

Naming your Var scoped variables

While there are no strict conventions when naming your Var scoped variables, be aware that a naming conflict will arise if your local variable name is the same as any defined argument name (or the name of another local variable).

<cffunction name="baseNumber" returnType="numeric">
<cfargument name="x" type="numeric" required="true" />
<cfset Var x = arguments.x />
<cfreturn x />
</cffunction>

Listing 1.18 baseNumber function

For example, if we have written the baseNumber() method as in the previous code, with the argument and local variable both called x, this would display an error, as a local variable within a function cannot be declared twice.

Accessing your CFC


Once you are ready to use your CFCs, you need to access the methods placed within. There are two ways to access a CFC:

  • object instantiation

  • invoking the CFC

Instantiating the object

When you instantiate a CFC, you create an instance of the component. This instance preserves the data within the CFC for as long as it exists. You would typically create an instance of a component at the top of the page. By doing so, you would have access to its methods and functions on the entire page, without having to create a new instance for each call.

There are three methods available to you to create an instance of the CFC:

  • createObject

  • cfobject

  • using the NEW operator in ColdFusion 9

Using the createObject function

As used in our earlier examples, the createObject() function creates and returns a ColdFusion object.

<cfscript>
objGreeting = createObject('component', 'greetings');
</cfscript>

Listing 1.19

Here, we are creating a new instance of the "greetings" component. The first parameter tells the createObject() function that we want a component, and the second references the name of the component of which we want to create an instance.

While the CFC is in the same directory as the calling page, in the previous example, if we had the CFC within a different directory in the webroot, for example, a folder named components; this second parameter would read as follows:

createObject('component', 'components.greetings');

This is because the second parameter is a dot notation representation of the path to the component.

Using the cfobject tag

Similar to the createObject() function, the cfobject tag has three attributes.

<cfobject name="greetingsObject" component="greetings" type="component" />

Listing 1.20

The name attribute defines the name of the returned variable of the CFC instance so you can access the component to use your methods. The component attribute represents a dot notation path to the CFC you wish to instantiate. The third attribute, type, is optional, and has the default value component.

Using the NEW operator

The enhancements in ColdFusion 9 now provide an alternative way of creating an instance of a component object without using the createObject() function.

We can now create the object through the use of the new operator, like so:

<cfscript>
// create the object
objGreeting = new greeting();
</cfscript>

Listing 1.21

Using cfinvoke

You can invoke your component and access the method simultaneously by using the cfinvoke tag. When you invoke (call) the CFC using this tag, you are not creating an instance of the component that will be preserved and available for use elsewhere within your CFML page. Instead, you are creating an instance of the CFC that comes into existence as soon as you invoke the method, and ceases to exist as soon as the requested method has returned a result.

In essence, you are bringing the component to life long enough to get the details you need from it and closing it down as soon as the information is returned.

The cfinvoke tag

Let's make a call to our sayHello() method within the greetings.cfc component.

Add the following code to your hello.cfm template page:

<cfinvoke component="greetings" method="sayHello" returnVariable="strHello" />
<cfoutput>#strHello#</cfoutput>

Listing 1.22

Here, we are invoking the greetings component, selecting the method within the CFC that we want to access, (in this case the sayHello() function) and assigning a variable (strHello), to which the returned data will be saved for us to access it within the page.

Outputting the returnVariable onto the page will provide us with the same result as we have seen before.

Using cfinvokeargument

The cfinvoke tag also allows us to pass in parameters to the methods we are calling, by means of the cfinvokeargument tag.

<cfinvoke component="greetings" method="personalGreeting" returnVariable="strPersonalGreeting">
<cfinvokeargument name="firstName" value="Matt" />
<cfinvokeargument name="lastName" value="James" />
</cfinvoke>

Listing 1.23

We are sending our parameters used in the personalGreeting() method in a similar format to the cfargument tag, using the cfinvokeargument tag, which is nested within the cfinvoke tag. The cfinvokeargument tag takes the name and value of the argument and sends it into the method you are calling.

Using attributes as arguments

Alternatively, when using the cfinvoke tag, you can send through the parameters as named attribute-value pairs, providing one attribute per argument.

<cfinvoke component="greetings" method="personalGreeting" firstName="Gary" lastName="Brown" returnVariable="strPersonalGreeting" />

Listing 1.24

You can see in the previous code that the firstName and lastName parameters are written as attributes within the cfinvoke tag itself.

Using an argument collection

The optional argumentCollection attribute for the cfinvoke tag accepts a structure in the form of an associative array of arguments to pass into the method.

<cfscript>
// create a structure to hold the values
stuArguments = structNew();
stuArguments.firstName = "James";
stuArguments.lastName = "Brown";
</cfscript>
<cfinvoke component="greetings" method="personalGreeting" argumentCollection="#stuArguments#" returnVariable="strPersonalGreeting" />

Listing 1.25

The structure names must match the names of the arguments within the method.

Passing arguments into an instance method call


As you have seen in the previous examples, we have sent parameters into the methods on our pages. There are two options available to send your arguments into your method call on an instantiated object.

As a list

You can send the two arguments through as a comma-delimited list. If you use this option, the order of the parameters you pass into the function call must match the order of arguments defined within the method.

In our personalGreeting() function the first name is the first argument, and the last name is the second argument, therefore you would do the following to call the method:

<cfset strPersonalGreeting = objGreeting.personalGreeting("Daft","Vader") />

Listing 1.26

As named values

An alternative method of sending arguments into a function is to use named values. This option ensures that the values passed through are assigned to the correct argument within the method. This means you do not have to place the parameters within the function call in any specific order, as the name of the parameter will match the name of the argument within the method.

<cfset strPersonalGreeting = objGreeting.personalGreeting(firstName="Daft",lastName="Vader") />

Listing 1.27

As an argumentCollection

As mentioned earlier, we also have the ability to send arguments through to the method using the argumentCollection attribute, and send through a structure of values.

Arguments in action


Let's look at another simple use case for creating reusable components and functions, which will also highlight some benefits of passing arguments into your methods.

Merging your functions into one

Create a new CFC called contacts.cfc, and add your cfcomponent tags to define the component.

Add the following method in the contacts.cfc file. This new function runs a SELECT query on the Project Tracker application database to retrieve a recordset of all contacts:

<cffunction name="getContacts">
<cfset var rstContacts = "" />
<cfquery name="rstContacts" datasource="projectTracker">
SELECT firstName,lastName FROM Owners
</cfquery>
<cfreturn rstContacts />
</cffunction>

Listing 1.28

We now have a function returning our query data. We also want to have a query to pull out a specific record based on the record ID of a particular person.

We can create a second function to handle this as well:

<cffunction name="getContact">
<cfargument name="ID" type="numeric" />
<cfset var rstContact = "" />
<cfquery name="rstContact" datasource="projectTracker">
SELECT firstName,lastName FROM Owners WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.ID#" />
</cfquery>
<cfreturn rstContact />
</cffunction>

Listing 1.29

These two methods within the contacts.cfc file interact with our database and return query data. However, the two queries pull out exactly the same information from the database. The only difference between the queries is that getContact() returns records for a specific user, based upon the ID value. We can easily streamline our CFC by combining these two methods into one, which will remove unnecessary code from our files and theoretically turn one function into two.

Using cfargument to combine your methods

In this example, we will combine the two SELECT queries into one method, using the cfargument tag.

<cffunction name="getContact">
<cfargument name="ID" type="numeric" default="0" />
<cfset var rstContact = "" />
<cfquery name="rstContact" datasource="projectTracker">
SELECT firstName,lastName FROM Owners
<cfif arguments.ID GT 0>
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.ID#" />
</cfif>
</cfquery>
<cfreturn rstContact />
</cffunction>

Listing 1.30

The cfargument tag has a default attribute, which allows you to provide a default value for an argument if you do not pass one into the method. As the customer ID parameter type is set to "numeric", we have set the default value of the argument to "0". This value will now always be available within our method and will stay at the default value until a parameter is passed in to the function.

By providing a default value, we are now able to wrap a cfif tag block around the WHERE clause of the query. If the value of arguments.ID (the value of the parameter within the arguments scope) is greater than 0, that is, if we have passed a numeric value into the method ourselves, then include the WHERE clause when running the SQL within the cfquery tags.

By doing this, we have merged the two methods within the contacts.cfc into one, optimizing our code and allowing it to perform more than one function.

Let's run this query. Create a new page template called query.cfm, and paste in the following code to create the object and run the method without sending in any parameters:

<!--- instantiate the object --->
<cfset objContacts = createObject('component', 'contacts') />
<!--- dump the results --->
<cfdump var="#objContacts.getContact()#" />

Listing 1.31

If no ID value is sent through as a parameter, meaning the default value is 0, the method will return the full recordset of all content from the Owners database table:

Amend the code by adding in a numeric value to pass through as the ID argument:

<!--- dump the results --->
<cfdump var="#objContacts.getContact(2)#" />

Listing 1.32

If we provide an ID within the argument, the method will only return the row for the contact that has the matching ID value:

The dumped object now shows us the parameter sent through in the arguments scope and the SQL query that now includes the WHERE clause.

The simple solution of using an argument with a default value and a cfif statement to control the flow has streamlined and reduced the amount of extraneous code within your application.

Creating an object constructor


In our contacts.cfc, we have defined a method which contains a query. This query has the datasource name attribute defined to correctly reference the database setup within the ColdFusion administration console.

As with all good development, we want to restrict hardcoding any values or references wherever we can and instead use variables to define them, (in this case the datasource name attribute).

A common practice in application development is to create your datasource name and store it in the Application scope, ensuring its availability to every page template that is called, for example:

<cfset application.dsn = "projectTracker" />

You could use the Application scope variable application.dsn directly within your CFCs as the dynamic name referencing the datasource. However, this is not considered best coding practice, as you have instantly opened up your component methods to a fixed scope variable.

One of the main goals in component development is to create closed CFCs and methods that do not need to worry about whether or not a fixed variable exists.

If we refer back to the getName() function on page 7, we can see how it was originally fixed to read the first and last name from the URL scope. We resolved that issue by removing any fixed scope references and optimized the method by adding cfargument tags and the ability to pass in parameters.

We will do the same for our contacts.cfc to send in our datasource name for use in the cfquery tags.

Instead of creating a new argument for each method within the component that requires the datasource, we will create a new function that will hold the variables we need and will be open for all methods defined within the CFC to read variables from.

Creating an init() function

Let's modify our code within the contacts.cfc gallery to write the new function, init().

<cfcomponent name="contacts">
<cffunction name="init">
<cfargument name="datasource" type="string" required="true" />
<cfscript>
Variables.attributes = structNew();
Variables.attributes.dsn = arguments.datasource;
</cfscript>
<cfreturn this />
</cffunction>
<cffunction name="getContact">
<cfargument name="ID" type="numeric" default="0" />
<cfset var rstContact = "" />
<cfquery name="rstContact" datasource="projectTracker">
SELECT firstName,lastName FROM Owners
<cfif arguments.ID GT 0>
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.ID#" />
</cfif>
</cfquery>
<cfreturn rstContact />
</cffunction>
</cfcomponent>

Listing 1.33

You can now see the init() method defined within the component. The concept of a constructor within an object is a common practice in most languages. We have included a cfargument tag with the name datasource, which will allow us to send in the name of the datasource we wish to use within this object.

Within the CFScript block, we then create a new structure that assigns the value of the datasource argument to the struct value dsn, and the structure has been assigned to the Variables scope within the CFC.

We can then amend our getContact() method and alter the datasource attribute to use the new reference, stored in the Variables scope:

<cffunction name="getContact">
<cfargument name="ID" type="numeric" default="0" />
<cfset var rstContact = "" />
<cfquery name="rstContact" datasource="#variables.attributes.dsn#">
SELECT firstName,lastName FROM Owners
<cfif arguments.ID GT 0>
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.ID#" />
</cfif>
</cfquery>
<cfreturn rstContact />
</cffunction>

Listing 1.34

By sending the value into the object constructor method when instantiating the component we have removed the hardcoded reference to the datasource.

The Variables scope

The Variables scope can be made available to the entire CFC by setting a value either within one of the methods or in the constructor. The value of that variable is then made available to any other method (including the constructor).

The Variables scope can be used in a similar way to storing values within the Application scope, whose values are always available throughout the entire application. This makes it ideal for sending in variables such as the datasource name.

Calling your init() function

To set the value of the datasource name into the Variables scope, we need to call the init function to pass through the argument.

In previous examples, we have already used the createObject() function to create an instance of the component. We are going to use exactly the same code, only this time we will append the init()function to the end of instantiation method call:

<!--- instantiate the object --->
<cfset objContacts = createObject('component', 'contacts').init(datasource="projectTracker") />

Listing 1.35

By doing this, we have passed our datasource name as an argument into the init() method within the contacts.cfc. The argument value is then stored within the Variables scope structure (Variables.attributes).

Note

Values stored within the Variables scope last as long as the component instance exists, and therefore can persist between calls to methods of a CFC instance.

The Variables scope within your CFC is available to any included pages (using the cfinclude tag), and any Variables scope variables that you have defined in the included page are also available to the CFC.

The This scope

At the end of the function, we have the cfreturn tag, which we have seen before. However, this particular method is returning a different value, which is This:

<cffunction name="init">
<cfreturn This />
</cffunction>

Listing 1.36

By adding a return type of This to the cfreturn tag, you are returning the entire object, including all of its methods, variables, and data.

In the query.cfm calling page, use the cfdump tag to display the object in the browser:

<!--- dump the contacts object --->
<cfdump var="#objContacts#" />

Listing 1.37

As the init() method returns the object in the This scope, we are able to access the object directly using the cfdump tag.

The This scope is similar to the Variables scope due to the fact that it is 'globally' accessible to the entire CFC. In addition, the This scope is accessible outside of the CFC, so you could call and reference the values from your object within your .cfm template calling page.

For example, if we amended the code within the init() method in the CFC from using the previously mentioned Variables scope to the This scope, we could access the datasource name from our calling page:

<cffunction name="init">
<cfargument name="datasource" required="true" />
<cfscript>
This.attributes = structNew();
This.attributes.dsn = arguments.datasource;
</cfscript>
<cfreturn This />
</cffunction>

Listing 1.38

In the query.cfm, we can now output the name of the datasource from the attributes structure stored within the This scope:

<!--- dump the contacts object --->
<cfdump var="#objContacts#" />
<cfoutput>The datasource name is #objContacts.attributes.dsn#</cfoutput>

Listing 1.39

Notice that the attributes structure is now publicly available, allowing us to access the name of the datasource directly from the CFC.

This highlights the difference between the Variables and This scope. When the attributes were assigned to the Variables scope, they were kept hidden from external views, despite being available to all methods within the CFC. As soon as we changed the init() method to store attributes within the This scope, the structure became a visible, 'public' variable that could be accessed outside of the CFC.

Although the This scope is a required tool for returning a complete CFC object, it is not best practice to store variables within the scope. This is because they can be accessed and altered. Unless you specifically choose to alter your object's variables in this manner, this would not be a safe development practice.

Note

Values stored within the This scope last as long as the component instance exists, and therefore can persist between calls to methods of a CFC instance.

Summary


We have looked at ColdFusion Components, what they are and what they are for. Within this chapter, we have also covered:

  • The basic structure of a CFC

  • The component tags

  • Grouping functions and methods

  • How to use arguments within your methods

  • Optimizing and encapsulating your functions to improve code portability

  • Instantiating your objects, as well as creating an object constructor method

  • The Arguments, This and Variables scope, and to Var scope function variables

Left arrow icon Right arrow icon

Key benefits

  • Fast-paced easy-to-follow guide introducing object-oriented programming for ColdFusion developers
  • Enhance your applications by building structured applications utilizing basic design patterns and object-oriented principles
  • Streamline your code base with reusable, modular objects
  • Packed with example code and useful snippets

Description

Are you tired of procedural programming or is your extensive code base starting to become un-manageable? Breathe some new life into your code and improve your development skills with the basic concepts of object-oriented programming. Utilize objects, modular components, and design patterns to expand your skills and improve your ColdFusion applications. Packed with example code, and written in a friendly, easy-to-read style, this book is just what you need if you are serious about ColdFusion.This book is a fast-paced tutorial to important ColdFusion object-oriented programming topics. It will give you clear, concise, and practical guidance to take you from the basics of ColdFusion to the skills that will make you a ColdFusion developer to be reckoned with. Don't be put off by jargon or complex diagrams; read and see how you can benefit from this book and extend your development skills in the process.Using the practical examples within this guide, you will learn how to structure your applications and code, applying the fundamental basics of object-oriented programming to develop modular, reusable components that will scale easily with your application. You will learn the basic fundamental practices of object-oriented programming, from object creation and re-use, to Bean objects, service layers, Data Access objects, and sample design patterns to gain a better understanding of OOP using examples that can be altered and applied in your application. Complete with detailed code samples and snippets, and written in a friendly easy-to-follow style, you will be able to break free from writing purely procedural code and enhance your applications by building structured applications utilizing basic design patterns and object-oriented principles.

Who is this book for?

If you are a web developer wanting to implement object-oriented programming with ColdFusion, then this book is for you. If your goal is to get a good grounding in the basics of object-oriented programming concepts, this book is perfect for you. No prior knowledge of object-oriented programming is expected, but basic knowledge of ColdFusion development skills is assumed.

What you will learn

  • Make your ColdFusion Components (CFCs) come alive with methods, using object inheritance, connecting to a database through the internal methods of our object/CFCs
  • Create a Bean object, complete with accessors and mutators to set and retrieve properties in the object, including sample code for ColdFusion 9 script components
  • Optimize and encapsulate your functions to improve code portability
  • Introduce the Bean into ColdFusion object-oriented programming design patterns, discover the benefits of code inheritance and understand polymorphism
  • Persist objects in memory throughout your applications
  • Examples of OOP concepts and basic design patterns
  • Create a service layer or fa?ßade to interact with your objects
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Oct 13, 2010
Length: 192 pages
Edition : 1st
Language : English
ISBN-13 : 9781847196323
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Publication date : Oct 13, 2010
Length: 192 pages
Edition : 1st
Language : English
ISBN-13 : 9781847196323
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 98.98
Object-Oriented Programming in ColdFusion
$43.99
ColdFusion 9 Developer Tutorial
$54.99
Total $ 98.98 Stars icon
Banner background image

Table of Contents

7 Chapters
Introducing ColdFusion Components Chevron down icon Chevron up icon
Effective Component Development Chevron down icon Chevron up icon
Building Your First Bean Chevron down icon Chevron up icon
Inheritance and Object-Oriented Concepts Chevron down icon Chevron up icon
Data Access Objects Chevron down icon Chevron up icon
Gateways Chevron down icon Chevron up icon
Creating a Service Layer Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5
(11 Ratings)
5 star 72.7%
4 star 9.1%
3 star 18.2%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




no ego Feb 06, 2020
Full star icon Full star icon Full star icon Full star icon Full star icon 5
What a great ColdFusion Book even in 2020. Just look at CF version adds and depreciations to lead you from this book to current. Hope the authors write a 2020 updated version!!
Amazon Verified review Amazon
RC Tupper Jun 17, 2011
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Coldfusion is a very different product than it was in the 90's. It's fast, it connects to anything and everything, and its a great server platform for a rich client style application. That said, there are right ways and wrong ways to develop in ColdFusion. This book will get you going in the right direction.
Amazon Verified review Amazon
Marcus Aug 20, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very very good introduction to OO programming in ColdFusion.If you're a relative beginner in OO or want to get into it, get this book.
Amazon Verified review Amazon
Robin Howland Jan 05, 2011
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you already have experience of ColdFusion and a are looking for help on structuring your code then this is the book to get.It will take you through the process or creating objects (CFCs) and get you used to the OOP style of separating the code from the detail in order to create flexible re-usable components.The book mostly utilises ColdFusion 8, but also has a few useful examples of creating objects with ColdFusion 9 (ie pure scripting without the ColdFusion tags for cleaner more concise code).I would have liked this to have been written a couple of years ago, but better late than never.
Amazon Verified review Amazon
Denard D. Springle IV Jan 11, 2011
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Matt has taken one of the most mystical topics with hard to cobble together bits of information about Object-Oriented Programming (OOP) in ColdFusion and put it all together into a single cohesive resource that will completely change the way you develop applications with ColdFusion. For years there have been a handful of us who sought out the practices and patterns of Object-Oriented Programming through examples in Java and other languages and implemented a variety of frameworks built around some of these fundamentals. Now, every ColdFusion programmer has a handy desk reference that goes under the hood of developing Object-Oriented Programming in ColdFusion with a grand presentation of both theory and practical application. Taking the reader from the core concepts of ColdFusion components through the use of components as objects gives even the novice ColdFusion developer all the information needed to start writing Object-Oriented applications. From beans, data access operations, gateways, services and the underlying principles of singleton's, inheritance and polymorphism to the application framework that underpins core Object-Oriented Programming functionality in ColdFusion, this book covers all the topics you need to get started. If you're at all serious about writing Object-Oriented ColdFusion applications, in any version of ColdFusion MX or higher, then this is the one resource you'll want to have on your desk - a to the point cookbook on how to implement Java style Object-Oriented Programming in your ColdFusion development.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela