public with sharing class projectSellStatusController {
// First
public list<projects__c> projectList {get;set;}
public projectSellStatusController(){
// Second
list<projects__c> projectList = [select name from projects__c];
}
}
The first variable can have its value set from anywhere in the class. But it starts out as null (referencing nothing) unless it is set to a value somewhere.
The second variable shadows (hides, masks) the first one. So this variable is set to the query results but because it is a local variable it is discarded at the end of the constructor (or of a method). So overall, no change is made to the first variable.
Removing the type to the left of the second variable name changes this from the declaration of a second variable to a reference to the first variable which is what is required here.
See e.g. Variable shadowing for more in-depth explanation. Note that unlike most languages, variable names in Apex are not case sensitive so e.g. abc
can shadow Abc
.
To directly answer the question in your title, you can't access a local variable in a Visualforce page: you must transfer the value to a class-level instance variable that follows the patterns described in the Apex Properties documentation. It is entirely appropriate to use local variables in the logic that works out a value and then set the result - that you want to reference in the page - in a property at the end of the logic. Just watch out for this shadowing problem.
Or another way to go is to set up the data within the property definition itself (here gaining the benefits of Lazy Loading too):
public with sharing class projectSellStatusController {
public list<projects__c> projectList {
get {
if (projectList == null) projectList = [select name from projects__c];
return projectList;
set;
}
}
This looks weird at first, but is idiomatic for Apex controllers.