View comments | RSS feed

Ensuring variable existence

ColdFusion generates an error if you try to use a variable value that does not exist. Therefore, before you use any variable whose value is assigned dynamically, you must ensure that a variable value exists. For example, if your application has a form, it must use some combination of requiring users to submit data in fields, providing default values for fields, and checking for the existence of field variable values before they are used.

There are several ways to ensure that a variable exists before you use it, including:

You can also use a cfform input tag with a hidden attribute to tell ColdFusion to display a helpful message to any user who does not enter data in a required field. For more information on this technique, see "Requiring users to enter values in form fields," in Chapter26.

Testing for a variable's existence

Before relying on a variable's existence in an application page, you can test to see if it exists by using the IsDefined function.

For example, if you submit a form with an unsettled check box, the action page does not get a variable for the check box. The following example from a form action page makes sure the Contractor check box Form variable exists before using it:

<cfif IsDefined("Form.Contractor")>
  <cfoutput>Contractor: #Form.Contractor#</cfoutput>
</cfif>

You must always enclose the argument passed to the IsDefined function in double quotes. For more information on the IsDefined function, see CFML Reference.

If you attempt to evaluate a variable that you did not define, ColdFusion cannot process the page and displays an error message. To help diagnose such problems, use the interactive debugger in ColdFusion Studio or turn on debugging in the ColdFusion Administrator. The Administrator debugging information shows which variables are being passed to your application pages.

Variable existence notes

If a variable is part of a scope that is available as a structure, you might get a minor performance increase by testing the variable's existence using the StructKeyExists function instead of the IsDefined function.

You can also determine which Form variables exist by inspecting the contents of the Form.fieldnames built-in variable. This variable contains a list of all the filed submitted by the form. Remember, however, that form Text fields are always submitted to the action page, and may contain an empty string if the user did not enter data.

The IsDefined function always Returns False if you specify an array or structure element using bracket notation. For example IsDefined("myArray[3]") always returns False, even if the array element myArray[3] has a value. To check for the existence of an array element, copy the element to a simple variable and use IsDefined to test whether the simple variable exists.

Using the cfparam tag

You can ensure that a variable exists by using the cfparam tag, which tests for the variable's existence and optionally supplies a default value if the variable does not exist. The cfparam tag has the following syntax:

<cfparam name="VariableName"
  type="data_type"
  default="DefaultValue">

Note:   For information on using the type attribute to validate the parameter data type, see CFML Reference.

There are two ways to use the cfparam tag to test for variable existence, depending on how you want the validation test to proceed:

The following example shows how to use the cfparam tag to check for the existence of an optional variable and to set a default value if the variable does not already exist:

<cfparam name="Form.Contract" default="Yes">

Example: testing for variables

Using the cfparam tag with the name attribute is one way to clearly define the variables that a page or a custom tag expects to receive before processing can proceed. This can make your code more readable, as well as easier to maintain and debug.

For example, the following cfparam tags indicate that this page expects two form variables named StartRow and RowsToFetch:

<cfparam name="Form.StartRow">
<cfparam name="Form.RowsToFetch">

If the page with these tags is called without either one of the form variables, an error occurs and the page stops processing. By default, ColdFusion displays an error message; you can also handle the error as described in Chapter 14, "Handling Errors".

Example: setting default values

The following example uses the cfparam tag to see if optional variables exist. If they do exist, processing continues. If they do not exist, the ColdFusion Server creates them and sets them to the default values.

<cfparam name="Cookie.SearchString" default="temple">
<cfparam name="Client.Color" default="Grey">
<cfparam name="ShowExtraInfo" default="No">

You can use cfparam to set default values for URL and Form variables, instead of using conditional logic. For example, you could include the following code on the action page to ensure that a SelectDepts variable exists:

<cfparam name="Form.SelectedDepts" default="Marketing,Sales">

ColdFusion 9 | ColdFusion 8 | ColdFusion MX 7 | ColdFusion MX 6.1 | ColdFusion MX | Forums | Developer Center | Bug Reporting

Version 6

Comments are no longer accepted for ColdFusion MX. ColdFusion 8 is the current version.

Comments


cannedRadio said on Jan 18, 2005 at 11:04 AM :
IsDefined("myArray[3]") does not return "false" it produces an error. Tested in CF 5, mx, mx 6.1. You can not check for the existence of an array element, by copying the element to a simple variable and use IsDefined to test whether the simple variable exists, because you get a error trying to use the array to set the simple variable.
here is a helpful udf with example you may use until CF can handle this requirement.

<cfscript>
function isArrayElementDefined(arrayName){
try{
testArrayVal = evaluate(arrayName);
return true;
}catch(any testForArrayElement){
return false;
}
}
</cfscript>
<cfset myArray = arrayNew(1)>
<cfset myArray[1] = "bob">
<cfset myArray[3] = "joe">
<cfoutput>
<cfloop from = "1" to = "3" index = "place">
#isArrayElementDefined("myArray[#place#]")#
</cfloop>
</cfoutput>

output: true false true
override11 said on May 8, 2006 at 6:36 AM :
Over at CFDJ, Charlie Arehart found a munch faster solution to this I thought I would share here:

Quoted from the article at <a href="http://cfdj.sys-con.com/read/41900.htm">http://cfdj.sys-con.com/read/41900.htm</a>

We mentioned earlier that prepopulating the array could solve the problem by ensuring there was always a value in each array element. That seems kludgy, especially doing some sort of loop to put a default value in each element and then testing for that default during each iteration through the array. Indeed, there are times when that wouldn't be appropriate anyway, since it may be significant that there's no value in particular array elements, or it may lead to lots of extra bytes of information in an otherwise large, sparse array.

Still, if that solution has appeal, there's still one more approach that may be at least a little less kludgy. Rather than loop through the array to prepopulate it (or deal with CFTRY/ CFCATCH to detect errors), you could use CFPARAM within the loop while iterating through the array. This will assign a default empty string to any array elements that are otherwise "not defined," then test for that value to determine which array elements have value. The change to the loop above would be:

<CFLOOP FROM="1" TO="#ArrayLen(ACart)#" INDEX="i">
<CFPARAM NAME="Acart[i]" DEFAULT="">
<CFIF Acart[i] is not "">
Item: #ACart[i]# <br>
</CFIF>
</CFLOOP>

CFPARAM says, "If the named variable doesn't exist, create it and populate it with the given default value." Now, unlike the test for IsDefined(), the test that follows will never result in a runtime error, and it'll only print an array element if it has content. (If you need to distinguish between an element whose value is already an empty string and one whose value is assigned via CFPARAM, change the DEFAULT and test using some other unlikely value.)

Thanks to developer Tim Painter and instructor Emily Kim, who both shared this solution with me.
timothyFarrar said on Jan 10, 2007 at 9:13 AM :
Hey guys,
Just wanted to let you know that the udf from "CannedRadio", really helped me. I am inside a loop looking ahead of myself to check a value, and I needed to make sure that the iterator of my inner loop was a valid array element number. The others may have worked also, but this one was the clearest one I could impliment. P.S. Shouldnt one of these functions be added to CF? It only seems logical that they would have it built in for us to be able to check to see if an array element existed.

Thanks though,
Timothy D Farar

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/coldfusion/6/Developing_ColdFusion_MX_Applications_with_CFML/Variables8.htm