function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sflearnsflearn 

Getter and Setter Question

Learning about properties and how come the output of my page is   'ConstructorValue' rather than 'ReplaceConstructorValue' when my setter is called right after the constructor initializes my message variable? Shouldn't message be set to 'ReplaceConstructorValue'?

 

 
public class myOrderTestController
{  
    public String message;
    public myOrderTestController()
    {
       //process constructor value
    }
    
    public void setMessage()
    {
      //  process ReplaceConstructorValue';    
    }   
    
    public String getMessage()
    {
  // return message
   }
}
Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

To cause an identical effect with what you're trying to do, you can use property getters and setters:

 

public class myOrderTestController {
  string m; // Private
  public String message { get { return m; } set { m = 'ReplaceConstructorValue'; /* ignores input value */ } }

  public myOrderTestController() {
    m = 'ConstructorValue';
  }
}

In this form, we have a "backing" value (m), and we use that to determine what "message" will display. In the constructor, "m" is set to "ConstructorValue", and Visualforce will call only a getter, thus honoring that original message. When a postback occurs (the form is submitted), the setter will set "m" to a new value, and when "get" is called during the page rendering phase, later, the message that appears will be the new message, not the original.

 

You can see this effect using this page:

 

<apex:page controller="myOrderTestController">
  <apex:form id="form">
    <apex:inputText value="{!message}"/>
    <apex:commandButton value="Update Message" reRender="form"/>
  </apex:form>
</apex:page>

Click the button, and the message will change from one to the other.

All Answers

Venkat PolisettiVenkat Polisetti

You never called setMessage() anywhere in your controller. You initialized message in your constructure and that is what the getMessage() sees in your outputText.

 

I prefer, properties rather than getters and setters. It is less code and less confusing.

 

Thanks,

sflearnsflearn

I also updated my code to see if I could call it this way but it outputed a null value. Is there a different way I could call my set method?

 

public class myOrderTestController
{
public String message;
public String m;
public myOrderTestController()
{
//process 'ConstructorValue';
}

public void setMessage()
{
//process 'ReplaceConstructorValue';

}

public String getMessage()
{
//return vqalue
}
}

sfdcfoxsfdcfox
public void setMessage() should be public void setMessage(String value). Then assign value to message (or m, if that's your intent). When an element doesn't have a getter and setter built in (e.g. public String message { get; set; }), Visualforce looks for functions with "getX" and "setX", where X is the name of the merge value (e.g {!x}). When using this design, you need to supply one parameter to the setX function, where the parameter is the correct data type for the element (should be the same as that returned by getX). Visualforce automatically submits the value to the first parameter (which I have called value, but you could name anything you want, such as foobarbaz).
sflearnsflearn
sfdcfox- thank you so much. I will try this and post my results but question I have is how would I get the same result by usng apex properties instead of getX and setX? Is this possible ?
sfdcfoxsfdcfox

To cause an identical effect with what you're trying to do, you can use property getters and setters:

 

public class myOrderTestController {
  string m; // Private
  public String message { get { return m; } set { m = 'ReplaceConstructorValue'; /* ignores input value */ } }

  public myOrderTestController() {
    m = 'ConstructorValue';
  }
}

In this form, we have a "backing" value (m), and we use that to determine what "message" will display. In the constructor, "m" is set to "ConstructorValue", and Visualforce will call only a getter, thus honoring that original message. When a postback occurs (the form is submitted), the setter will set "m" to a new value, and when "get" is called during the page rendering phase, later, the message that appears will be the new message, not the original.

 

You can see this effect using this page:

 

<apex:page controller="myOrderTestController">
  <apex:form id="form">
    <apex:inputText value="{!message}"/>
    <apex:commandButton value="Update Message" reRender="form"/>
  </apex:form>
</apex:page>

Click the button, and the message will change from one to the other.

This was selected as the best answer
sflearnsflearn

sfdcfox, this totally makes sense for properties with the post and and get request and how the get and set properties are used. However, for my first example, does that mean that I would essentially never do a post request since I am never really submitting?  I think this is why the code below will never display 'ReplaceConstructorValue' whether I use the getX /setX design or get / set properties design since my controller and markup below is only for page load(get request). ..is this correct?

 

public class myOrderTestController
{
public String message;
public myOrderTestController()
{
// process 'ConstructorValue';
}

public void setMessage(String m)
{
//process 'ReplaceConstructorValue';

}

public String getMessage()
{
//process return message;
}
}

 

<apex:page controller="myOrderTestController">
<apex:form >
<apex:pageBlock title="Test">

<apex:outputtext value="{!message}">
</apex:outputtext>
</apex:pageBlock>
</apex:form>
</apex:page>

sfdcfoxsfdcfox
Correct. "setMessage()" won't be called until you do a post-back via any form element capable of performing a postback (actionSupport, actionFunction, commandButton, commandLink, or actionPoller). So, lacking these elements, the code you posted is incapable of having the message change from its original value.
sflearnsflearn

thank you sfdcfox - this thread was very helpful. you rock=)

sflearnsflearn

Is there a best practice of when to use get/set properties only versus getX / setX methods or a combination of both? 

sfdcfoxsfdcfox

The best approach depends on several factors. Personal preference is one. I prefer set/set instead of setX/getX in most cases, because it makes the rest of my Apex Code more readable. That is to say:

 

x.setA(x.setB(x.setC(0)));

 Is less readable than:

 

x.a = x.b = x.c = 0;

Especially when the symbols are longer (i.e. actual function names we would use in code).

 

However, you can't address set/get in an actionFunction directly, so there are times when you might need to use a setter/getter method instead. Some people prefer function notation anyways, so the former method would be okay.

 

In general, if there may be side effects, use getX/setX, or if you need to address the value in Visualforce remoting or actionFunctions, otherwise you can feel free to use get/set.

 

Other than that, major considerations for which to use are a matter of corporate or department policy (e.g. we will always use get/set when possible, or always use getX/setX), and to make sure that exceptions are documented. A developer looking at your code shouldn't have to guess if the variable is initialized in a constructor or a get/set pair. 

 

Also, using get/set is generally considered an "advanced" topic, so writing code this way may slow down others working on your code (if any). While code comments are always important, they are doubly so when using get/set methods.