Oh my god. It's full of code!

Correct me if I’m wrong…

But it seems to me I may have found what I would consider to be a bug in Salesforce custom components. When you create a component (a reusable piece of code that can be put into visualforce pages) you can specify attributes it accepts. Basically data you can give to the component when you call it, that it will need to function properly. If you had a component to make a phone call, you might need to pass it a phone number as an attribute (also known in other languages as a parameter or argument). Of course not every attribute may be required every time (maybe you don’t need to include the country code every time in your component that makes calls). So then you can set a default value. Which is a value that will be used if when called, one is not provided. These are really handy because you can make many parts of your component configurable, without having to specify each and every option every time (it’s nice to have the option of setting some obscure font color, but if you don’t care its just extra work. Nice to have a default).

Here is where it gets a little weird. When you call your component (likely from a visualforce page) you pass in the attributes for it to use. However, those attributes may themselves be variable (say you wanted to pass in the current time, you cannot hard code that, you’d need a variable that evaluates at run time). If you have a default value set on an attribute, you cannot pass in a variable. If you do not have a default you can. If you try, you’ll get the error

‘Error: Literal value is required for attribute’

Basically saying, it doesn’t want to evaluate the variable before passing it along to the component. You have to remove the default value from the apex:attribute tag. This is a bummer because say you want to pass in a variable, but have no idea if that variable will actually contain a value (if you are reading a contacts phone number to send, but no phone number is on that record, you just pass along an empty string). So your component can end up running with a null value where it may be expecting a number or string. This can cause issues. You could probably manually test for a null in your attribute in the component and assign a value if it is, but that is extra work. I see no reason for this behavior, but then again I’m dumb as a box of rocks. Anyway, I just figured I’d write this because I know I spent a while trying to figure out the fix. So long story story short, if attempting to pass a dynamic value to your component, your must not have a default value attribute in the attribute tag.

For those curious, below is the code I was working on (some data changed, but structure remains the same). You’ll see that some of my attributes do not have default values, that is because they may be dynamic in some instances.

Visualforce Page

<apex:page standardController="Contact">
    <c:vf_gauge minVal="0"
        maxVal="0"
        currentVal="{!contact.warnings__c}" 
        backgroundColor="blue"
        fontColor="red"
        title="How close to banning"
        link="http://www.google.com"
        animate="false"/>
</apex:page>

Component

<apex:component >
   
    <apex:attribute name="minVal" type="string" description="the minimum value" required="true"/>
    <apex:attribute name="maxVal" type="string" description="the maximum value" required="true" />
    <apex:attribute name="currentVal" type="string" description="the current value" required="true" />
    <apex:attribute name="backgroundColor" type="string" description="the color of the numeric readout box" default="black"/>
    <apex:attribute name="fontColor" type="string" description="the color of the font in the readout box" default="white"/>
    <apex:attribute name="title" type="string" description="A title for this gauge" default="My awesome gauge"/>
    <apex:attribute name="link" type="string" description="A url to go to when gauge is clicked" default="#"/>
    <apex:attribute name="animate" type="boolean" description="animate the line" default="true"/>
//other code

</apex:component>

One response

  1. ken

    Dan,

    I’m not thinking it is a bug, but one of those behaviors that we have to learn about on the platform. It seems like the documentation always falls just a little short of what I need, and I have to poke around to figure out when things go wrong. I attribute it to being a configurator’s platform that is only just beginning to embrace the development community… and it IS getting better.

    Thanks for the great explanation.
    –k

    June 30, 2011 at 8:12 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s