• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Component properties don't exist anymore.

Enthusiast ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

I have an component called: Event.cfc

Long story short, I init() it by issuing a command like:

<cfset eventObject = new 'com.Event'() />

This component has 2 properties: data (a structure) and name (a string).

The init() method calls a private method:

<cfset VARIABLES.setName( VARIABLES.getAttribute( 'event' ) ) />

The setName() method is implicit, ColdFusion builds it based on the name attribute.  I manually created the getAttribute() method which works with the data property.  In the getAttribute() method, I have a command that reads:

<cfset LOCAL.retVar = VARIABLES.data[ ARGUMENTS.attributeName ] />

Well, CF keeps saying that 'data' does not exist in VARIABLES.  But I thought that properties that were defined in a component were put into the VARIABLES scope.  So how can this variable NOT exist when I have it defined at the top of the Event.cfc component as a <cfproperty>?

Views

1.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Oct 31, 2013 Oct 31, 2013

Aegis,

From the new CF10 docs it looks like <cfproperty> doesn't quite work like you thought:


Usage

You must position cfproperty tags at the beginning of a component, above executable code and function definitions. If a component is not used as a web service,  only provides metadata information of the property. It does not define variables or set values that you can use in your component. However, it creates implicit setters and getters for the property in the CFC depending on whether getter/setter

...

Votes

Translate

Translate
Guide ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

Can you post the entire actual code of the Event.cfc component?

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

<!---

          <!--- ******************************************************************************************************************* --->

          <!--- ******************************************************************************************************************* --->

          Name:                     Event object component.

          File:                              Event.cfc

          Desc:                              Handles View-initiated Event objects.

          Version:          1.0.0 (2013-10-10T12:00:00-0500)

          Todo:                              [none]

          <!--- ******************************************************************************************************************* --->

          <!--- ******************************************************************************************************************* --->

--->

<cfcomponent

          output                     = "false"

          accessors          = "true">

          <!--- =================================================================================================================== --->

          <!--- =================================================================================================================== --->

          <!--- Component methods (explicit):

                                        :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

                                        Component methods (implicit):

                                        :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

                                        Component properties:

                                        :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

                                        Private variables:

                                        :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

                                        Public variables:

                                        --->

          <!--- =================================================================================================================== --->

          <!--- =================================================================================================================== --->

          <!--- Component properties: --->

          <cfproperty

                    required          = "true"

                    type                              = "struct"

                    name                              = "data"

                    getter                    = "false"

                    setter                    = "false" />

          <cfproperty

                    required          = "true"

                    type                              = "string"

                    name                              = "name" />

          <!--- =================================================================================================================== --->

          <!--- =================================================================================================================== --->

          <!---          Method: init(). --->

          <cffunction

                    access                              = "public"

                    returntype          = "Event"

                    name                                        = "init"

                    output                              = "false">

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Arguments. --->

                    <cfargument

                              required          = "true"

                              type                              = "struct"

                              name                              = "constructorData"

                              default                    = "#{ 'event' = '' }#" />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Set LOCAL variables: --->

                    <cfset LOCAL.attributeName = '' />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Set instance variables: --->

                    <cfset VARIABLES.setName( VARIABLES.getAttribute( 'event' ) ) />

                    <cfif structCount( ARGUMENTS.constructorData )>

                              <cfloop collection="#ARGUMENTS.constructorData#" item="LOCAL.attributeName">

                                        <cfset VARIABLES.setAttribute( LOCAL.attributeName, ARGUMENTS.constructorData[ LOCAL.attributeName ] ) />

                              </cfloop>

                    </cfif>

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!---          Return.          --->

                    <cfreturn THIS />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

          </cffunction>

          <!--- =================================================================================================================== --->

          <!--- =================================================================================================================== --->

          <!---          Method: getAttribute(). --->

          <cffunction

                    access                              = "private"

                    returntype          = "any"

                    name                                        = "getAttribute"

                    output                              = "false">

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Arguments. --->

                    <cfargument

                              required          = "true"

                              type                              = "string"

                              name                              = "attributeName" />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Set LOCAL variables: --->

                    <cfset LOCAL.retVar = '' />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Capture the attribute value: --->

                    <cfset LOCAL.retVar = VARIABLES.data[ ARGUMENTS.attributeName ] />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!---          Return.          --->

                    <cfreturn LOCAL.retVar />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

          </cffunction>

          <!--- =================================================================================================================== --->

          <!--- =================================================================================================================== --->

          <!---          Method: setAttribute(). --->

          <cffunction

                    access                              = "private"

                    returntype          = "void"

                    name                                        = "setAttribute"

                    output                              = "false">

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Arguments. --->

                    <cfargument

                              required          = "true"

                              type                              = "string"

                              name                              = "attributeName" />

                    <cfargument

                              required          = "true"

                              type                              = "any"

                              name                              = "attributeValue" />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- Store the attribute value: --->

                    <cfset structInsert( VARIABLES.data, ARGUMENTS.attributeName, ARGUMENTS.attributeValue, true ) />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!---          Return.          --->

                    <cfreturn />

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

                    <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->

          </cffunction>

          <!--- =================================================================================================================== --->

          <!--- =================================================================================================================== --->

</cfcomponent>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

I'm chewing through the code.  Next time, please don't post all that whitespace (it looks like a Ben Nadel blog post sample).   Just as a suggestion, you might want to take a look at the ColdBox CFML Standards and Best Practices guide as a way to make code a bit more readable for yourself and others.  I found it to be pretty good.

Anyway, I'll get back to you in a bit if I can figure something out.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

Aegis,


What version of CF are you using?

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

ColdFusion 10 Developer.

And sorry about that.  I should have killed the whitespace.  I like my code having "breathing room" and only related "clumps" of code stick close together.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

Aegis,

From the new CF10 docs it looks like <cfproperty> doesn't quite work like you thought:


Usage

You must position cfproperty tags at the beginning of a component, above executable code and function definitions. If a component is not used as a web service,  only provides metadata information of the property. It does not define variables or set values that you can use in your component. However, it creates implicit setters and getters for the property in the CFC depending on whether getter/setter attributes are enabled.

Notice the part I italicized - it does not define the variables.  You'll need to add a pseudo-constructor to create the variables before the init() method.

Not necessarily related, but something I noticed.  In your init() method you have this:

<cfset VARIABLES.setName( VARIABLES.getAttribute( 'event' ) ) />

On a newly created object, the data variable will be empty so calling your getAttribute() method won't return anything (and may error since there won't be an 'event' struct key inside the 'data' variable).

Also, on methods inside your component, you don't need to call them with the "VARIABLES." scope prefix.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

Wow.  I can't believe I had been coding and things were working (by haphazzard chance it would seem) up til now, but that's a great piece of info.

So I'll need to explicitly set VARIABLES in the component's pseudo constructor eh?  OK, That should be doable. 

As for the setName() being called on the getAttribute(), I think I flubbed up.  I need to perform the setAttribute loop FIRST, and then once the attributes are set, THEN run that line of code, and it will get the 'event' attribute from the data structure and use it for the event Name.  Good catch Carl!

Sorry if all the scoping is unnecessary.  I sometimes scope heavily as a previous belief that it is a good practice.  I guess I can keep the variables scoped, but leave off the scope for method calls.  Makes sense.

I'm also reading up on that coding standards documentation you linked me to.  Carl, you are a freaking wealth of good information.  You ever drop down my neck of the woods, I owe ya a steak dinner and drinks.  Much appreciated!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

One area that Naming Convention website hits on is that it talks about storing my instance-based variables in 'variables.instance', a structure that I create in the 'init()' method.

My only problem with doing this is, if I understand it correctly, this means I cannot use CF's implicit getters and setters.  Because as I understand it, if you set 'accessors="true"' on the component, and you have a property, say:

<cfproperty required="true" type="string" name="age" />

Then CF will create a getAge() and setAge() method, but the problem is that it references 'variables.age' and not 'variables.instance.age'.  This would mean I would have to manually create the accessor and mutator methods if I use 'variables.instance'.

...And on a sidenote, I really wish CF would allow me to specify the access property on implicit getter/setters.  I think it defaults them to public, but there are many times I'd love to make a read-only bean, and set the setter's access to private, but again, unless I manually code it, I don't think I can do that.  Maybe CF11?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 31, 2013 Oct 31, 2013

Copy link to clipboard

Copied

On an ADDITIONAL sidenote, I'm seeing an odd problem here.  My directory structure is as follows:

(site root)/www/com/domain/fw/Event.cfc

As you can see, the first subdirectory off my site root is 'www', well in my site root I have folders which all map to different subdomains.  (this maps to 'www.domain.com')  The problem here is that the "returnType" for these objects is:

www.com.domain.fw.Event

It seems I have to hardcode this value into these CFC's because putting a variable in there is not allowed.  So if I had another folder at root, let's say, called 'clients', and it was running a separate application off the same framework, I'd have to go to every CFC and change 'www.com.domain.fw.Event' to 'clients.com.domain.fw.Event'.

I'd love to find a dynamic way to do that.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Nov 01, 2013 Nov 01, 2013

Copy link to clipboard

Copied

How about adding a mapping to one of those folders in your chain (maybe 'fw')?  I'm not sure, but I think you can dynamically build the mapping based on the current context.  Then you could refer to the objects as "fw.Event" instead.  Do you have separate application.cfc files in each site?

I gotta dash for a bit, I'll circle back when I get back in the office.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 01, 2013 Nov 01, 2013

Copy link to clipboard

Copied

LATEST

To this point I had always assumed CF per-application mappings were for just file/folder pathing, and did not equate it to the fully qualified dot-notation that CFCs use.  I don't see why that shouldn't work.  Great idea!  That way I can keep the CFCs in the framework specifying a package that is: [mapping].path.to.object.

As for separate application.cfc files, well, it all depends if I'm hosting a separate app on a separate subdomain.

For example:

www.domain.com runs off of /[siteroot]/www/  -> It uses an application

cdn.domain.com runs off of /[siteroot]/cdn/  -> Since it just hosts files, there IS an application.cfc in there, but it's a "nullifyer application.cfc" designed to just prevent CF from traversing up out of the subdomain folder and hitting another application.cfc.

And take your time, Carl.  I'm extremely appreciative that you're helping me understand this and have provided such great solutions.  It really shows me how much more "out of the box" I need to think when taking on these problems.  I sincerely appreciate your time!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation