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
Alan ZieglerAlan Ziegler 

Getting a record using a private instance of standard controller in a standard controller extension

All but the last few lines of code below are copied from other discussions/documentation about how to override a save action using a private instance of a standard controller for a selected record in a standard controller extension.  I am trying to provide a way to return the selected record back to page.  My getLeadRecord below gets message "System.NullPointerException: Attempt to de-reference a null object"

Controller extension code is below.  I have simplified select statement to just get ID of first Lead record:

public with sharing class LeadNameLookupConExt {

  public LeadNameLookupConExt(ApexPages.StandardController controller){ }

  private ApexPages.StandardController ctrl;
  public Lead guest {get;set;}
  public LeadNameLookupConExt(){
    try{
      guest = [select ID from Lead limit 1];
          //where name = : ApexPages.currentPage().getParameters().get('guest')];
    } catch (QueryException e) {
      guest = new Lead();
    }
      ctrl = new ApexPages.StandardController(guest);
  }
   public PageReference save(){
    return ctrl.save();
  }
// my added get record code trying to get record object of the specific controller instance
  public Lead getLeadRecord(){
    return (Lead)ctrl.getRecord();
  }
}


my page code is

<apex:page standardController="Lead" extensions="LeadNameLookupConExt">
<form >
<input value="{!LeadRecord.ID}"/>
</form>
</apex:page>


Incidentally, I can retrieve the record if I convert this into a custom controller, but I need a standard controller extension.
Best Answer chosen by Alan Ziegler
Prateek Singh SengarPrateek Singh Sengar
Hi Alan,
There are multiple things missing.
1) What is the use case of this code? Are you trying to embed the vf in a page layout. If so the standardController.getRecord() will fetch you the information.
2) Select using Name in where clause has possibility of returning more than 1 value. How do you want to handle this scenario.
3) Passing the Lead name in get parameter and querying the information and displaying the value is not the right use case for an extension. Extension by defenation should extend the capabilities for standard controller. 

However if you just want to see how it will work please try the below code. I have tried it in my dev sandbox and it works. Hope this helps.
 
Apex Class

public class LeadNameLookupConExt {

    private Lead LeadRec;
    
    public Lead getLeadRecord()
    {
        //get the value of parameter
        String leadName = ApexPages.currentPage().getParameters().get('guest');
        system.debug('leadName'+ leadName);
        LeadRec = [Select id,Name from Lead where Name =:leadName limit 1];
        return LeadRec;
    }
    
    
    public LeadNameLookupConExt(ApexPages.StandardController controller)
    {
        //initialize to avoid null exception
        LeadRec = new Lead();
     }
}
 
<apex:page standardController="Lead" extensions="LeadNameLookupConExt">
<form >
<input value="{!LeadRecord.ID}"/>
</form>
</apex:page>

in URL use
https://c.na30.visual.force.com/apex/LeadView?guest=Norm%20May

Please note that salutation is not part of the Lead Name. To get the exact lead name query the lead name in query editor.

All Answers

Prateek Singh SengarPrateek Singh Sengar
Can you try modifying the constructor 
 
public LeadNameLookupConExt(ApexPages.StandardController controller)
{
  guest = (Lead)controller.getRecord() ;  
}

You will not need your getLeadrecord method and in your visualforce page instead of {!LeadRecord.Id} use {!guest.Id}
Alan ZieglerAlan Ziegler
Thanks for your response.  I tried this change as written and several variations and it would not compile.  I am not sure this would get me the right record anyway because I want the record found by the select and this change removes the select statement.  Incidentally, I did try making getLeadRecord just return guest and then referred to {!guest.ID} on page, but this gives me null value.on page (perhaps better than an error message but still no success).  However, the above syntax and returning guest works just fine as a custom controller but does not work as soon as I insert the second line to turn this into a standard controller extension. When returning guest in a controller extension did not work,  I tried returning something else I thought the controller extension would know: private instance of controller's (which uses select statement) record().  There seems to be something different about this syntax in controller extensions versus custom controllers that I don't yet understand.
Alan ZieglerAlan Ziegler
Sorry, in above response I should have said after returning guest in my method,  I referred to both {!guest.ID} and {!LeadRecord.ID} neither of which worked (but work just fine as a custom controller)..
Prateek Singh SengarPrateek Singh Sengar
Hi Alan,
There are multiple things missing.
1) What is the use case of this code? Are you trying to embed the vf in a page layout. If so the standardController.getRecord() will fetch you the information.
2) Select using Name in where clause has possibility of returning more than 1 value. How do you want to handle this scenario.
3) Passing the Lead name in get parameter and querying the information and displaying the value is not the right use case for an extension. Extension by defenation should extend the capabilities for standard controller. 

However if you just want to see how it will work please try the below code. I have tried it in my dev sandbox and it works. Hope this helps.
 
Apex Class

public class LeadNameLookupConExt {

    private Lead LeadRec;
    
    public Lead getLeadRecord()
    {
        //get the value of parameter
        String leadName = ApexPages.currentPage().getParameters().get('guest');
        system.debug('leadName'+ leadName);
        LeadRec = [Select id,Name from Lead where Name =:leadName limit 1];
        return LeadRec;
    }
    
    
    public LeadNameLookupConExt(ApexPages.StandardController controller)
    {
        //initialize to avoid null exception
        LeadRec = new Lead();
     }
}
 
<apex:page standardController="Lead" extensions="LeadNameLookupConExt">
<form >
<input value="{!LeadRecord.ID}"/>
</form>
</apex:page>

in URL use
https://c.na30.visual.force.com/apex/LeadView?guest=Norm%20May

Please note that salutation is not part of the Lead Name. To get the exact lead name query the lead name in query editor.
This was selected as the best answer
Alan ZieglerAlan Ziegler
Thanks a bunch!  Your syntax works beautifully.

The limited documentation I could find on when to use controller extensions versus custom controllers seems to indicate that if I want to use both standard controller methods plus my own custom method, I should use an extension, but the advice seems to be very rule of thumb. I put much more faith in the developer community advice.

Other limited documentation seems to indicate that if I create a custom controller I can still access standard controller methods if I want to redefine all of them within the custom controller but suggests if that is what I am doing, I should just use an extension.

I did not try embedding the "controller" logic in vf page, but I bet your syntax or my custom controller syntax would work there.  Limited documentation again suggested that data access should be put in a controller versus vf page as a rule of thumb.

I simplified the example and explanation with regard to making sure I get only one record but I appreciate your reminder that I must handle this.

Again thanks a bunch!
Prateek Singh SengarPrateek Singh Sengar
Hi Alan,
Yes i would agree that you would use extension when you want to leverage the standard controller funcitonality and enhance it with custom code. Since your code is a snippet of your actual code it makes sense to use extension. From my experience in working on force.com platform I would say there is no rule of thumb there are recommendations and best practices but they could vary based on each use case.