6

I came across this question somewhere which has been kept me engaged thinking why it is behaving this way.

Lets say I have an apex class:

public class TestController {
    public String  myString{get;set;}

    public String getStringmethod1()
    {
        System.debug('myString'+myString);
        return myString;
    }

    public String getStringmethod2()
    {
        System.debug('myString'+myString);
        if(myString == null)
            myString = 'Something';
        return myString;
    }

    public String getStringmethod3()
    {
        System.debug('myString'+myString);
        myString += 'Special';
        return mySTring;
    }
}

And a visualforce page:

<apex:page controller="TestController">
    {!myString}, {!Stringmethod1}, {!Stringmethod2}, {!myString}, {!Stringmethod3}, {!myString}
</apex:page>

I was expecting the output to be

, , Something, Something, SomethingSpecial, SomethingSpecial

But the output is:

, , Something, , SomethingSpecial,

So even after, inside the get methods, setting the myString property value, whenever I try to access the property directly again, I am getting null value. Its not reflecting the change done in getter method.

But again, when I am accessing the same myString property inside a getter method, I am seeing that its holding the changed value, not null anymore.

I am sure I am failing to understand the behavior of getter methods. Could anyone please explain this behavior? Whats happening here?

  • From documentation- A property with only a get accessor is considered read-only. – Raul Apr 12 '17 at 14:34
  • Yes, but I have set accessor as well on the property, myString. – Santanu Halder Apr 12 '17 at 14:40
  • From experience, getter's do not update any other properties. You should do it in action method or a constructor. – Raul Apr 12 '17 at 14:42
  • Agreed that getters dont update the property value, but why in the getStringmethod3 I am getting the value set in getStringmethod2 method? – Santanu Halder Apr 12 '17 at 15:00
  • 2
    I tried this and getter is called only once. Can it be something related to cache ? salesforce.stackexchange.com/questions/97059/… – Muzammil Bajaria Apr 12 '17 at 17:13
4

I have observed Apex properties - a convenient way to implement getters and setters - only being referenced once even though the Visualforce includes multiple references. It seems like there is some caching of values being done but I don't remember seeing any documentation that guarantees that behaviour. So if you want to check the same in your code please do the following changes and check the debug log : -

Apex class

public String  myString{
    get{
        System.debug('-----'+myString);
        return myString;
    }
    set;
}

In Your VF page made below changes :

<apex:page controller="TestController">
   <!-- {!myString}, {!Stringmethod1}, {!Stringmethod2}, {!myString}, {!Stringmethod3}, {!myString}-->
   {!myString},{!myString},{!myString}//make the change by only calling "myString" thrice 
</apex:page>

Now if you open the debug log and check it will only calls once in spite of calling the same thrice from the page.

The first time "myString" is referenced in Visualforce Page is done and the value assigned to the field. On subsequent references the field value is returned without the assignment being done. An advantage of this pattern over setting the properties in the constructor is that if the set of properties referenced varies depending on conditional page logic then only the initialization for the properties that are actually referenced is done so avoiding the waste of calculating the unreferenced properties. The approach works equally well for static fields.

2

In salesforce "get" method is used to pass data from your Apex code to your Visualforce page and "set" is used to pass data/value from visualforce page to the controller variable.

So basically when you refer a get set variable on VF, the "get" method gets called, and when you change it's value the set method get called.

e.g:
//Apex class
public class GetSetDemo
{  
    public String inputval;
    public String getinputval(){return 'Nil';} //getter for variable

    public void setinputval(String inputval)
    {
        this.inputval = inputval;
    }   
}

//VF
<apex:page controller="GetSetDemo">
  <apex:form>
    <apex:outputlabel value="Enter your name here"/>
       <apex:inputtext value="{!inputval}">
           <apex:actionsupport event="onclick" rerender="display" />
       </apex:inputtext>                   
    <apex:outputpanel id="display">
        <apex:outputtext value="The entered value is {!inputval}"/>
    </apex:outputpanel>                   
  </apex:form>    
</apex:page> 

Now, whatever value you enter the page always displays "The entered value is Nil".... This is because your get method always returns 'Nil'... but still your set method will store the value you entered in the variable "inputval".

So, i entered "Nilesh" in the input field it returns me "The entered value is Nil" because the get method is returning 'nil', but in the apex i am getting it's actual entered value "Nilesh"

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.