1

I am creating a product selection process via a custom apex controller and visualforce page.

When the page is rendered it gives the error message "Attempt to de-reference a null object".

The end of the error log says the problem is with a query that is being attempted. Backtracking in the log for the data that should be used for the query the following error is found.

    11:55:33.0 (9330713)|VARIABLE_ASSIGNMENT|[7]|priceBooks|"List of size 6 too large to display"|0x43d8a527

The line that is causing the null object error is the query in the following block of code, attempting to get a selection of price books from the database.

  public queryProduct( ) {
    //Getting list of price books to show user.
    List<Pricebook2> priceBooks = [select id, name from PriceBook2 where isActive=True];
    System.debug( 'Price books ' + priceBooks);
    for( Pricebook2 a : priceBooks ) {
        pricebook_name.add( new SelectOption( a.Id, a.Name ) ); 
    }
}

The code is being used on the visualforce page in the following way.

    <apex:pageBlockSection title="Pricebook selection">
    <apex:form >
        <apex:outputLabel value="Which Pricebook? :"/>
        <apex:selectList value="{!selected_Pricebook}" size="1">
            <apex:selectOptions value="{!pricebook_name}"/>
        </apex:selectList>
        <br /><br />
        <apex:commandButton value="Search records" action="{!search}" rerender="out"/>
        <apex:commandButton value="Clear records" action="{!clear}"/> 
    </apex:form>
</apex:pageBlockSection> 

User will select one and then get a list of all products in that book, to then ultimately select a product, to be used later in a process that is being developed.

I don't understand why this bit of code isn't working. The System.debug message in the log reflects that the records in questions are found and being displayed, at least in the log. Why is the code crashing out like this?

Editing to add more detail So I thought I was starting to understand better, but guess not. Here are the full code pages I am working with.

Apex Class

public class queryProduct {
List<SelectOption> pricebook_name {get;set;}
public string selected_Pricebook {get;set;}

public queryProduct( ) {
    List<selectOption> pricebook_name;
    //pricebook_name= new List<SelectOption>();
    //Getting list of price books to show user.
    List<Pricebook2> priceBooks = [select id, name from PriceBook2 where isActive=True];
    //System.debug( 'Price books ' + priceBooks);
    system.debug(string.valueOf(pricebook_name));
    for( Pricebook2 a : priceBooks ) {
        pricebook_name.add( new SelectOption( a.Id, a.Name ) ); 
    }
}
public void search(){
    List<SelectOption> options;
    List<PricebookEntry> productList = [select Name, Product2Id from PriceBookEntry where Pricebook2Id=:selected_Pricebook];
    for( PricebookEntry aa : productList ) {
        options.add(new SelectOption( aa.Product2Id, aa.Name));
    }
}
public void clear(){
    //pricebook_name.clear();
} 

}

VF Page

<apex:page Controller="queryProduct"> 

<apex:pageBlockSection title="Pricebook selection">
    <apex:form >
        <apex:outputLabel value="Which Pricebook? :"/>
        <apex:selectList value="{!selected_Pricebook}" size="1">
            <apex:selectOptions value="{!pricebook_name}"/>
        </apex:selectList>
        <br /><br />
        <apex:commandButton value="Search records" action="{!search}" rerender="out"/>
        <apex:commandButton value="Clear records" action="{!clear}"/> 
    </apex:form>
</apex:pageBlockSection> 

I am now getting the error Unknown property 'queryProduct.pricebook_name' when trying to save the VF page. I ''think'' I have the getter set and the var initialized, but I am doing something wrong here still it seems. What am I not understanding here?

  • How is your pricebook_name declared? It seems that you haven't initialized the variable and are trying to add the select options in it directly which is causing a null pointer exception. – Jayant Das Nov 5 '18 at 19:47
  • Please note, I have edited the question title to reflect your actual issue. – Jayant Das Nov 5 '18 at 19:56
  • Thanks for the edit on the title, I wasn't fully understanding what was going on. – PHonnold Nov 5 '18 at 20:39
3

You're question title is mis-leading. The "too large to display" error is simply because you can only fit so many characters on a single line in the debug logs. Instead of printing the entire array of price books, in your loop add system.debug(string.valueof(a)).

In terms of your actual error my best bet is that pricebook_name appears to be a list. Make sure you initialize the list with pricebook_name = new List<selectOption>(); You can verify this by using system.debug(string.valueOf(pricebook_name)); before your loop.

When you see attempt to deference a null object you should always look for the . character in your code. This character is the deference operator. This means that what ever is to the left of the . character is null. You're code only has a deference in a few places but the only one likely to through an error is the one I mentioned above.

  • So it seems I don't fully understand variable assignment here. I had the following assignment outside the code block that was shown. public List<SelectOption> pricebook_name; I tried the option that was posted above 'pricebook_name = new List<selectOption>();' but got the error message that the pricebook_name variable could not be found. I had to change it to the setup that Jayant Das talked about below 'List<SelectOption> pricebook_name = new List<SelectOption>();' Testing this fully right now, but not sure why the one worked and the other didn't. – PHonnold Nov 5 '18 at 20:42
  • @PHonnold - because you are using pricebook_name on the VF page, so you need to have it declared at the class level (outside the method where you are populating it) with a getter method. And that the variable needs to be initialized, so that you can add values in it. – Jayant Das Nov 5 '18 at 21:05
  • The difference between pricebook_name = new List<SelectOption(); and List<SelectOption> pricebook_name = new List<SelectOption(); is simply that in the latter you declare and initialize in the same line. In the former it assumes you declare the variable earlier in the code using List<SelectOption> pricebook_name; and then you call pricebook_name = new List<SelectOption>(); on a different line. Ultimately, they accomplish the exact same thing. – gNerb Nov 5 '18 at 22:45
2

Your potential issue is on this line for the NullPointerException.

pricebook_name.add( new SelectOption( a.Id, a.Name ) ); 

And it seems that pricebook_name may not have been initialized. That will be the only scenario, when you will get the NPE as you are experiencing.

You should verify if the variable has been initialized before you are adding values in it.

A typical variable declaration and initialization here would look like as below, before you can actually add values in it. Note that you won't get any error during compile time but only run-time as you are experiencing.

List<SelectOption> pricebook_name = new List<SelectOption>();
0

The standard pattern for this is (lazy load):

public SelectOption[] availablePricebooks {
  get {
    if (availablePricebooks == null) { // lazy load
       availablePricebooks = new List<SelectOption> ();
       for (Pricebook pb : [Select Id, Name, ... From Pricebook Where ...]) {
         availablePricebooks.add(new SelectOption (pb.Name,pb.Name));
       }
    }
    return availablePricebooks; // assumes no new pricebooks are being created by user
 } private set;
}
public String selectedPricebook {get; set;}

Note use of plurals for collections - a huge boon in debugging/readable code

and VF ...

<apex:selectList value="{!selectedPricebook}" size="1">
        <apex:selectOptions value="{!availablePricebooks}"/>
</apex:selectList>

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.