Archive for the ‘ColdFusion’ Category

Consuming Webservices with Complex Input Parameters

Wednesday, November 7th, 2007

ColdFusion sometimes has trouble assembling the inputs to a web service when the parameters to the web service function are complex. I ran into trouble recently when trying to use the findObjects() method of the API-A interface to a Fedora Commons repository.

There is a discussion of this issue in the adobe forums with a good description of ColdFusion's behavior when preparing parameters for a web service call.

(more...)

URLEncoded Arguments of a Remote Component Function

Monday, December 11th, 2006

There are a number of ways to invoke functions of a ColdFusion component:

Code (coldfusion)
  1. <cfinvoke component="#myCfc#" method="helloworld">
  2.   <cfargument name="input" value="Hello World!">
  3. </cfinvoke>
  4. <cfset myCfc.helloworld("Hello World!")>
  5. <a href="/my.cfc?method=helloworld&input=Hello%20World!">Invoke Component Function</a>
  6. <form action="/my.cfc" method="post">
  7.   <input type="hidden" name="method" value="helloworld" />
  8.   <input type="text" name="input" value="Hello World!" />
  9.   <input type="submit" name="submit" value="Invoke Component Function" />
  10. </form>

In addition, you can invoke a function through Flash Remoting or as a Web Service.

I recently discovered that if you invoke a remote function through a URL or a form on a web page, the arguments are automatically URLDecoded for you before the function is invoked.

I had some input in a form that included a '+' character. The browser naturally encoded the '+' into '%2B' before posting to my component function, as it should. Then ColdFusion (behind the scenes) decoded the string back to '+' before calling my function.

The problem was that in my function, which I knew was being called from a form, I immediately called URLDecode() on my input, to convert any instances of '%xx' to the correct character. Well, a '+' represents a [space] in a URL-Encoded string, so the '+' that was in the original input ended up as a [space].

The moral of the story is to be aware that ColdFusion will automatically URLDecode arguments from the URL or form before invoking your remote component method being invoked directly.

GRG 301K Place Name Exam - Google Map

Wednesday, November 15th, 2006

I developed a nice little web page as an exercise in Google Maps and to help study for a Place Name Exam in one of my classes, GRG 301K. The test is over a set of locations. A map with numbers will be provided and each question will name a location and ask (multiple choice) which location on the map matches that name. My Place Name Exam - Google Map page is a tool to help study for the exam.

The locations are divided up into categories (as provided by the professor). Clicking on a category on the left will bring up markers on the map corresponding to the locations in the category. Clicking a marker will identify the location in an info window/balloon. Clicking a particular location within a category will center the map on the marker for that particular location.

(more...)

Instantiation order with extended components

Wednesday, November 8th, 2006

The particular order that a child and parent component are instantiated should be noted. The initialization code, that is, the code in a component that is outside cffunction tags, is executed first in the parent. For example, if you have a parent/base component:

Code (coldfusion)
  1. <!--- employee --->
  2. <cfcomponent>
  3.   <cfset this.salary = 50000>
  4.   <cfset init()>
  5.   <cffunction name="init" access="public" returntype="employee">
  6.     <cfset this.overtimeSalary = this.salary * otMult()>
  7.   </cffunction>
  8.   <cffunction name="otMult" access="private">
  9.     <cfreturn 1.5>
  10.   </cffunction>
  11. </cfcomponent>
and a child component:
Code (coldfusion)
  1. <!--- manager --->
  2. <cfcomponent extends="employee">
  3.   <cfset this.salary = 70000>
  4.   <cffunction name="init" access="public" returntype="manager">
  5.     ...
  6.   </cffunction>
  7.   <cffunction name="otMult" access="private">
  8.     <cfreturn 2>
  9.   </cffunction>
  10. </cfcomponent>

then instantiating an object of type Manager will have a salary property set to 70000, because the cfset runs in Employee first, and then in Manager.

This makes pretty good sense to me. The values of the child component override the values set in the parent.

This doesn't apply only to variables being set, though (whether it be the public this scope or the private variables scope). If you call a function from the initialization code of a parent component, the function is called as it exists in the parent - the child part of the object has not been instantiated yet.

So with the example components above, the call to init() from within the initialization code of the parent component, Employer, makes a reference to the otMult() function. Since the child part of the object has not been instantiated yet, the otMult() call returns 1.5, instead of the value of 2 you might want if you are instantiating a Manager.

If this becomes a problem for you, I suggest that you NOT try to call your initialization functions from the initialization code block of a component, and instead, put all your initialization code within init functions and call your init() function when you instantiate an object:

Code (coldfusion)
  1. <cfset myManager = CreateObject("component", "Manager").init()>

Happy Coding!