1

The setup: I have a standard controller with two extensions on it.

<apex:page
    standardController="Contact"
    showQuickActionVfHeader="false"
    extensions="ExtOne,ExtTwo">

    <c:ExtraInformation titleFieldKeys="Test1,Test2"/>

    <script>
        const values = '{!value}';
    </script>

</apex:page>

The controller also has a custom component on it, which should be piping the property on it onto my extension:

<apex:component controller="ExtTwo">
    <apex:attribute
        name="titleFieldKeys"
        type="String"
        assignTo="{!extraInfoTitleFieldKeys}"/>
</apex:component>

The code on the extension is as follows:

public with sharing class ExtTwo {

    public Apexpages.StandardController scon {get; set;}
    public String extraInfoTitleFieldKeys {get; set;}

    //  Apparently for custom components to work on extensions, you need
    //  to overload the constructor....
    public ExtTwo() {}

    public ExtTwo(Apexpages.StandardController scon) {
        this.scon = scon;
    }

    public String getValue() {

        Map<String, Object> record = new Map<String, Object>();

        record.put('extra', extraInfoTitleFieldKeys);

        return JSON.serialize(record);
    }
}

All of this seems pretty straightforward to me. But the issue I'm having is that the value, after being sent into the Setter, will not be retrieved by the Getter during the getValue call. I have tried everything I can think of, but it seems as though the value is just vanishing. I went as far as to explode the getter/setter out into their own methods:

    public String extraInfoTitleFieldKeysInternal = '';

    public void setExtraInfoTitleFieldKeys(String input){
        System.debug('setting setExtraInfoTitleFieldKeys to '+input);
        this.extraInfoTitleFieldKeysInternal = input;
        System.debug('setExtraInfoTitleFieldKeys set: '+extraInfoTitleFieldKeysInternal);
    }

    public String getExtraInfoTitleFieldKeys(){
        System.debug('getting extraInfoTitleFieldKeys: '+extraInfoTitleFieldKeysInternal);
        return this.extraInfoTitleFieldKeysInternal;
    }

The debug log shows that yes, input is set to the value I specified in the visualforce page, and extraInfoTitleFieldKeysInternal is showing that it is being set to the value of input as you would assume. However, when I call getExtraInfoTitleFieldKeys, it logs that extraInfoTitleFieldKeysInternal is null. The setter is triggering long before the getter, so it's not a race condition.

The only movement I could get is if I set extraInfoTitleFieldKeysInternal to some initial value - in that case, the setter would register setting what I specified in the visualforce page, but the getter would stubbornly return the value from the initialized extraInfoTitleFieldKeysInternal.

I've been at this for hours now and I've run out of ideas. I'll be perfectly happy at this point if it's something glaringly obvious. I just need this to work!

  • you should also show the VF markup (essential bits) for the action method invocation/{!value} references – cropredy Nov 11 '19 at 19:47
  • @cropredy Updated. – carnoldus Nov 11 '19 at 21:13
0

This is what is happening:

  • The VF page is instantiating two controller objects ExtOne, ExtTwo
  • The custom VF component is instantiating a third controller object ExtTwo
  • The JS line const values = '{!value}'; is invoking the getter on the page's ExtTwo object. But that object's setter public String extraInfoTitleFieldKeys {get; set;} is never invoked; it is the second ExtTwo object's setter that is invoked via the component's assignTo="{!extraInfoTitleFieldKeys}".

Hence, the JS getter (which references the page's controller, not the component's controller) fetches a null value

|improve this answer|||||
  • Oh man I would have never figured that out I don't think. Thank you! Okay, so that means then that the component is instantiating its own controller? That explains the need for the second constructor. Ugh. Okay, what I'm trying to do here is pass an arbitrary value to my controller that I can define on my VF page. I guess components aren't the way to do that. Can you recommend a way to get the value of 'Test1,Test2' to the Ext2 extension on the controller? – carnoldus Nov 11 '19 at 23:45
  • o that means then that the component is instantiating its own controller? = YES. You should accept this answer and then pose a different question because it is not clear what you are trying to achieve. The new question should include an example of your intent – cropredy Nov 11 '19 at 23:48
  • Actually, now that i step back I think I'm just over-complicating what I'm attempting to do. I'll try another approach. Thanks again. – carnoldus Nov 12 '19 at 0:27
  • cool -- I don't think I have ever used the same class for both the page controller and the custom component controller. Separation of Concerns and all that. – cropredy Nov 12 '19 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.