0

This is my first time having built a custom controller, and I in a revolving door of errors: This is the code with which I begin, and this DOES work:

apex:

<apex:page controller="AccountCustomController" >
    <apex:form >
        <apex:pageBlock title="Congratulations {!$User.FirstName}">
            <apex:commandButton action="{!savetherecord}" value="Save"/>
        </apex:pageBlock>
    </apex:form>
</apex:page>

custom controller:

public class AccountCustomController 
{
    private final Account myaccount;
    public PageReference savetherecord() 
    {
        update myaccount;
        return null;
    }

    public String getAccount() 
    {
        update myaccount;
        return null;
    }

    Public AccountCustomController()
    {
        myaccount = [Select id, Name, Site from Account where id =: ApexPages.currentPage().getParameters().get('id')];
    }
}

Then, I add one line to the Apex code, beneath the Congratulations:

<apex:page controller="AccountCustomController" >
    <apex:form >
        <apex:pageBlock title="Congratulations {!$User.FirstName}">
            **You belong to account name: <apex:inputfield value="{!myaccount.name}"/>**
            <apex:commandButton action="{!savetherecord}" value="Save"/>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Then, I get the error: "Error: Unknown property 'AccountCustomController.myaccount'", and it offers to insert the property "AccountCustomController.myaccount" or the method "AccountCustomController.getmyaccount".

I choose "AccountCustomController.myaccount", and get the VisualForce error: "Duplicate field: myaccount".

When I refresh the screen, I get the VisualForce error "System.QueryException: List has no rows for assignment to SObject". At that point, I have to add the inputfield again, and I have come around, once again, to the entrance point of the revolving door. Please help. Thank you.

1

The main issues here are:

  • You define myaccount as a private variable
  • It's a variable, not a property

The private access modifier keyword makes it so that only the class that the variable is defined in (and any inner classes it contains) can access it. Your Visualforce page uses your custom controller, but it is not itself the controller, so you don't have access to it.

The error message reflects that. It's not saying "You have a duplicate value", but rather "You told me to use this variable, but I don't have permission access to it".

The other thing with accessing controller variables in a Visualforce page is that they need to have getter and setter methods. A variable on its own cannot be accessed by a Visualforce page. Providing a getter and setter (or maybe just a getter) is what distinguishes a variable from a property.

You can do that in one of two ways:

  • put {get; set;} after the class variable definition, e.g. public myAccount {get; set;}, which automatically generates a basic getter and setter
  • declare explicit getter/setter methods following Salesforce's convention of get|set + variable name, e.g. public Account getMyAccount(){ return myAccount; }

So in the end, simply updating your custom controller from
private final Account myaccount;
to
public Account myaccount {get; set;}
should do the trick

I had thought that the final keyword would be problematic, but testing shows that it doesn't really have an effect. It still feels like bad practice though (something that can potentially cause weird issues).

0

Got it, finally!

Apex:

<apex:page controller="AccountCustomController" >
    <apex:form >
        <apex:pageBlock title="Congratulations {!$User.FirstName}">
            You belong to account name: <apex:inputfield value="{!myaccount.name}" />
            <apex:commandButton action="{!savetherecord}" value="Save"/>
        </apex:pageBlock>
    </apex:form>
</apex:page>

custom controller:

public class AccountCustomController 
{
    Public final Account getaccount;
    
    Public Account myaccount
    {
        get 
        { 
            return getaccount; 
        }
    }

    public PageReference savetherecord() 
    {
        update getaccount;
        return null;
    }

    public String getAccount() 
    {
        update getaccount;
        return null;
    }

    Public AccountCustomController()
    {
        getaccount = [Select id, Name, Site from Account where id =: ApexPages.currentPage().getParameters().get('id')];
    }
}

The problem was that the Apex wanted a property, and I was giving it a variable. I had to modify the code from the way the instructor had posted it, which likely reflects a change from the versions the instructor and I use. I'm pleased to have figured this one out myself!

2
  • public final Account getAccount { get; set; } would have worked just as well. Also, you don't need to return a null page reference on an action function; just specify it as a void return type: public void savetherecord() { update getaccount; } – sfdcfox Feb 26 at 2:24
  • Also, arguably, you should use standardController and extensions (if necessary) on your page. You don't even need a controller for this task. – sfdcfox Feb 26 at 2:25

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.