4

ORIGINAL POST:

I'm flumoxed. I thought my constructor WASN'T returning a value.

This is code that gets an AggregateResult value via SOQL and then puts the info into an object so that it can be used to create a Gauge chart.

Can someone please tell me what I need to do to fix this? And be gentle - I'm a newbie. :-)

public class GaugeChartController{

public String acctId { get; set; }
public List<Test__c> testList { get; set; }
public gaugeData[] data { get; set; }

public GaugeChartController(ApexPages.StandardController controller) {
        acctId = controller.getRecord().Id;
}

public GaugeChartController() {

    // query to see if there is at least one row of data for this account
    testList = [select ScorePos__c from Test__c where Account_Name__c =: acctId 
                and CreatedDate = YESTERDAY LIMIT 1];

    // Test the value from the query above for existence and size
    if(testList != null && testList.size() > 0){

        // The test worked, so now we can run the real query
        // Create an aggregate result called AHCValues that sums the ScorePos field and outputs a single value
        AggregateResult AHCValues = [select SUM(ScorePos__c) totalScore from Test__c where Account_Name__c =: acctId  and CreatedDate = YESTERDAY GROUP BY CALENDAR_MONTH(CreatedDate) LIMIT 1];

        List<gaugeData> data = new List<gaugeData>();

        // Add in the name ("100 - x"), and score (60) values
        data.add(new gaugeData('100 - ' + Integer.valueOf(AHCValues.get('totalScore')), Integer.valueOf(AHCValues.get('totalScore')))); 

        return data;
    } else {
        // Else if the test had no rows, hand this error to the Apex Page so it can be output in place of the gauge
        ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'No results for this Account.');
        ApexPages.addMessage(myMsg);
    }  
}   

// Class to hold the data for the gauge
public class gaugeData {
    public String name { get; private set; }
    public Integer size { get; private set; }   

    public gaugeData(String name, Integer data) {
        this.name = name;
        this.size = data;
    }
} }

UPDATE TAKING RALPH'S COMMENTS INTO ACCOUNT

With this, there are no errors, but {!data.size} is empty on the VF page:

public class GaugeChartController{

public String acctId { get;set; }
public List<Test__c> testList { get; set; }
public gaugeData[] data { get; set; }

public GaugeChartController(ApexPages.StandardController controller){
    // Use built-in function to get the Account ID for the page that we are on
    acctId = controller.getRecord().Id;

    // query to see if there is at least one row of data for this account
    testList = [select Score__c from Test__c where Account_Name__c =: acctId 
        and CreatedDate = YESTERDAY LIMIT 1];

    // Test the value from the query above for existence and size
    if(testList != null && testList.size() > 0){

        // The test worked, so now we can run the real query
        // Create an aggregate result called AHCValues that sums the ScorePos field and outputs a single value
        AggregateResult AHCValues = [select SUM(Score__c) negScore, SUM(ScorePos__c) posScore from Test__c where Account_Name__c =: acctId 
                                    and CreatedDate = YESTERDAY GROUP BY CALENDAR_MONTH(CreatedDate) LIMIT 1];

        // Instantiate a list to hold the data in the format that the gauge chart needs
        List<gaugeData> data = new List<gaugeData>();
        // Add in the name ("100 - x"), and score (-60) values
        data.add(new gaugeData('100 - ' + Integer.valueOf(AHCValues.get('posScore')), 
                              Integer.valueOf(AHCValues.get('negScore')))); 
    } else {
        // Else if the test had no rows, hand this error to the Apex Page so it can be output in place of the gauge
        ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'No results for this Account.');
        ApexPages.addMessage(myMsg);
    }
}

// Class to hold the data for the gauge
public class gaugeData {
  public String name { get; set; }
  public Integer size { get; set; }   

  public gaugeData(String name, Integer size) {
      this.name = name;
      this.size = size;
  }
}

}

1
  • 1
    Constructor can't return any data Whereas u use return data where u can use values of data directly in any other method only u need to not empty the list and ur error will resolve.
    – Tepsi
    Dec 19, 2013 at 5:38

3 Answers 3

3

You're shadowing your class level variable with a local function variable by the same name.

Fix this line:

List<gaugeData> data = new List<gaugeData>();

To read like this:

data = new List<gaugeData>();

"Scope" is the life-time during which a variable may be visible. Scope is defined at three levels: local, instance, and static. Due to scope resolution, it's possible to have at least two of the three variables in existence at once. You can also have a class and function that share the same name (as in this intentionally confusing example):

public class a {
    public integer a = 5;
    public void a() {
        integer a = 7;
        System.debug(this.a * a); // Prints 35!
    }
    public a() {
        a();
    }
}

Just remember that a locally declared variable will always take precedence over an instance or static variable of the same name. Use "this.variable" to get to the instance version (literally, "this", as outlined in the prior example), and use "class.variable" to get to the static version (class should be replaced with the name of the class, for example, "a").

1

Only you need to cooment the return data .

public class GaugeChartController{

public String acctId { get; set; }
public List<Test__c> testList { get; set; }
public gaugeData[] data { get; set; }

public GaugeChartController(ApexPages.StandardController controller) {
    acctId = controller.getRecord().Id;
}

public GaugeChartController() {

// query to see if there is at least one row of data for this account
testList = [select ScorePos__c from Test__c where Account_Name__c =: acctId 
            and CreatedDate = YESTERDAY LIMIT 1];

// Test the value from the query above for existence and size
if(testList != null && testList.size() > 0){

    // The test worked, so now we can run the real query
    // Create an aggregate result called AHCValues that sums the ScorePos field and outputs a single value
    AggregateResult AHCValues = [select SUM(ScorePos__c) totalScore from Test__c where Account_Name__c =: acctId  and CreatedDate = YESTERDAY GROUP BY CALENDAR_MONTH(CreatedDate) LIMIT 1];

    List<gaugeData> data = new List<gaugeData>();

    // Add in the name ("100 - x"), and score (60) values
    data.add(new gaugeData('100 - ' + Integer.valueOf(AHCValues.get('totalScore')), 
                           Integer.valueOf(AHCValues.get('totalScore')))); 

   // return data;
} else {
    // Else if the test had no rows, hand this error to the Apex Page so it can be output in place of the gauge
    ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'No results for this Account.');
    ApexPages.addMessage(myMsg);
}  
}   

// Class to hold the data for the gauge
public class gaugeData {
public String name { get; private set; }
public Integer size { get; private set; }   

public gaugeData(String name, Integer data) {
    this.name = name;
    this.size = data;
}
}
4
  • Store the size of data in any variable and use it on ur page in first constructor
    – Tepsi
    Dec 19, 2013 at 5:48
  • Isn't that what data.add is doing? Dec 19, 2013 at 5:57
  • data is a list which store values not size if you want to get size (how many records in the list) you nead to use integer int= data.size(); which gives u the size of ur list.
    – Tepsi
    Dec 19, 2013 at 6:39
  • Ah, I see. What I'm actually trying to get is the value of SUM(Score__c) into the "size" variable of the data object, to pass to the Gauge Chart in the VF Page. Dec 19, 2013 at 6:44
1

Looks like you've got a return call in your second constructor, return data;, remove that and you should be good.

Following up on your comments, if you want data to have a value, you'll need your code to get executed. If you just merge the two constructors you'll be good. For example

public class GaugeChartController{

public String acctId { get; set; }
public List<Test__c> testList { get; set; }
public gaugeData[] data { get; set; }

public GaugeChartController(ApexPages.StandardController controller) {
        acctId = controller.getRecord().Id;

    // query to see if there is at least one row of data for this account
    testList = [select ScorePos__c from Test__c where Account_Name__c =: acctId 
                and CreatedDate = YESTERDAY LIMIT 1];

    // Test the value from the query above for existence and size
    if(testList != null && testList.size() > 0){

        // The test worked, so now we can run the real query
        // Create an aggregate result called AHCValues that sums the ScorePos field and outputs a single value
        AggregateResult AHCValues = [select SUM(ScorePos__c) totalScore from Test__c where Account_Name__c =: acctId  and CreatedDate = YESTERDAY GROUP BY CALENDAR_MONTH(CreatedDate) LIMIT 1];

        List<gaugeData> data = new List<gaugeData>();

        // Add in the name ("100 - x"), and score (60) values
        data.add(new gaugeData('100 - ' + Integer.valueOf(AHCValues.get('totalScore')), 
                               Integer.valueOf(AHCValues.get('totalScore')))); 

    } else {
        // Else if the test had no rows, hand this error to the Apex Page so it can be output in place of the gauge
        ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'No results for this Account.');
        ApexPages.addMessage(myMsg);
    }  
}   

// Class to hold the data for the gauge
public class gaugeData {
    public String name { get; private set; }
    public Integer size { get; private set; }   

    public gaugeData(String name, Integer data) {
        this.name = name;
        this.size = data;
    }
}
}
7
  • I tried that but then it doesn't return any data. The vf page that renders the chart has no value for {!data.size}. I thought that was because I'm not including a return value somewhere... :-( Dec 19, 2013 at 5:42
  • That's because the other constructor never gets called, only the one with the standard controller input. Just combine your two constructors and ditch the return call and you should be good. Dec 19, 2013 at 5:44
  • Sadly, I've tried that as well and no dice. It's still returning null. I'll paste what I have now and perhaps someone can something else in error? Dec 19, 2013 at 5:57
  • Updated the answer to show what I meant by merging the constructors. It might help to try out some of the tutorials for visualforce, i.e. the visualforce workbook. Dec 19, 2013 at 6:02
  • Thanks, Ralph. As you can see, that's what I had but I'm still not getting any values in {!data.size}. I guess I should re-evaluate using the class and see if there's something I'm missing. Dec 19, 2013 at 6:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .