1

I am receiving an "Attempt to de-reference a null object" error.

It seems to be located somewhere in getUnconvertedProducts() because the lines it gives are the call for GenerateAccountProducts() in ActionAccountProductRun(), and in the for statement of GenerateAccountProducts().

I think it should be instantiating every variable up to that point, so I'm at a loss trying to find the error.

public class AccountProductExtension {

    public Account thisAccount;
    public String industry;

    public List<AccountProduct__c> accountProducts {get;set;}

    public Date checkBackDate {get;set;}
    public String productName {get;set;}

    public AccountProductExtension(ApexPages.StandardController controller) {
        this.thisAccount = (Account)controller.getRecord();

        //this.thisAccount = new Account(Id = '001560000038nY7');    

    }

    public void ActionAccountProductRun(){
        UpdateAccountProducts();
        GenerateAccountProducts();
        accountProducts = getAccountProducts();
    }

    public List<Product2> getUnconvertedProducts(){
        List<Id> productIds = new List<Id>();

        for(AccountProduct__c a :getAccountProducts()){
            productIds.add(a.Product__c);
        }

        List<Product2> productsToConvert = new List<Product2>([SELECT Id, Name, Account_Relatable__c, RecordTypeName__c, Industry__c FROM Product2 WHERE Id NOT IN :productIds AND Account_Relatable__c = true AND Industry__c != null]);
        List<Product2> convertP = new List<Product2>();
        if(industry != null){
            for (Product2 p:productsToConvert){
                if(p.Industry__c != null || p.Industry__c != ''){
                    List<String> industryList = new List<String>(); 
                    industryList = p.Industry__c.split(';');
                    for (String i:industryList){
                        if(i == industry){
                            convertP.add(p);
                        }
                    }
                }
            }
            return convertP;
        }
        else{
            System.Debug('There is no Industry on ' + thisAccount.Name + '. Please add an Industry and try again.');
            return null;
        }

    }

    public void GenerateAccountProducts(){
        List<AccountProduct__c> accountProductsToInsert = new List<AccountProduct__c>();

        for (Product2 p :getUnconvertedProducts()){
            AccountProduct__c newAP = new AccountProduct__c();
            newAP.Name = p.Name;
            newAP.Account__c = thisAccount.Id;
            newAP.Product__c = p.Id;
            newAP.Type__c = p.RecordTypeName__c;
            accountProductsToInsert.add(newAP);
        }
        insert accountProductsToInsert;
    }

    public List<AccountProduct__c> getAccountProducts(){
        List<AccountProduct__c> aProducts = new List<AccountProduct__c>([SELECT Id, Name, Account__c, Product__c, Type__c, Status__c, DateOffered__c, CheckBackDate__c, Notes__c FROM AccountProduct__c WHERE Account__c = :thisAccount.Id]);
        return aProducts;
    }

    public void UpdateAccountProducts(){

        for(AccountProduct__c ap : getAccountProducts()){
            Product2 product = [SELECT Id, Name, RecordTypeName__c FROM Product2 WHERE Id = :ap.Product__c];
            ap.Name = product.Name;
            ap.Type__c = product.RecordTypeName__c;
            update ap;
        }

    }

    public void autosave(){
        update accountProducts;
    }

    public void sendTask(){
        Task productTask = new Task();
        productTask.WhatId = thisAccount.Id;
        productTask.ActivityDate = checkBackDate;
        productTask.Type = 'Follow Up';
        productTask.Status = 'Not Started';
        productTask.Priority = 'Normal';
        productTask.Description = 'Please call the person in charge of the training curriculum with ' + thisAccount.Name + ' and take some time to speak with them regarding ' + productName;
        productTask.Subject = 'PRODUCTS - Check back with ' + thisAccount.Name + ' regarding ' + productName;

        insert productTask;
    }

}

Visualforce Page:

<apex:page showHeader="false" sidebar="false" standardController="Account" extensions="AccountProductExtension" action="{!ActionAccountProductRun}">

    <apex:form >
    <apex:outputText ><apex:param name="{!Account.Industry}" value="{!Account.Industry}" assignTo="{!industry}"/></apex:outputText>
    <apex:pageBlock title="Associated Products and Services">
        <apex:pageBlockButtons location="Top">

        </apex:pageBlockButtons>

        <apex:pageBlockTable value="{!accountProducts}" var="p">
            <apex:column headerValue="Product or Service" value="{!p.name}"/>
            <apex:column title="Type" value="{!p.Type__c}"/>

            <apex:column headerValue="Status">
                <apex:inputField value="{!p.Status__c}"/>
            </apex:column>

            <apex:column headerValue="Date Offered">
                <apex:inputField value="{!p.DateOffered__c}"/>
            </apex:column>

            <apex:column headerValue="Check Back On">
                <apex:inputField value="{!p.CheckBackDate__c}">
                    <apex:actionSupport event="onchange" oncomplete="Confirm();" reRender="out">
                        <apex:param name="cDate" value="{!p.CheckBackDate__c}" assignTo="{!checkBackDate}"/>
                        <apex:param name="pName" value="{!JSENCODE(p.name)}" assignTo="{!productName}"/>
                    </apex:actionSupport>
                </apex:inputField>
            </apex:column>

            <apex:column headerValue="Notes">
                <apex:inputField value="{!p.Notes__c}"/>
            </apex:column>
        </apex:pageBlockTable>

    </apex:pageBlock>
        <script>
        window.setTimeout(recursivecall,500);

        function recursivecall()
        {
          window.setTimeout(recursivecall,500);
          autosave();
        }

        function Confirm() {

            if ( confirm("Would you like to set a reminder to check back with the TA of {!Account.Name}?")){
                sendTask();
            }

        }    
        </script>

    <apex:actionFunction name="sendTask" action="{!sendTask}" reRender="out"/>
    <apex:actionFunction name="autosave" action="{!autosave}" reRender="out"/>
    </apex:form>

    <script>
        setFocus = function() { return; }
    </script>
</apex:page>

Full Error:

Visualforce Error
Help for this Page

System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!ActionAccountProductRun}' in component <apex:page> in page accountproductview: Class.AccountProductExtension.GenerateAccountProducts: line 55, column 1
Class.AccountProductExtension.ActionAccountProductRun: line 20, column 1

Class.AccountProductExtension.GenerateAccountProducts: line 55, column 1
Class.AccountProductExtension.ActionAccountProductRun: line 20, column 1
7
  • Is there not a stack trace?
    – Adrian Larson
    Dec 7, 2015 at 22:29
  • One obvious thing to check is that all your Product2 records have Industry__c filled in. You could do this via SOQL.
    – Adrian Larson
    Dec 7, 2015 at 22:30
  • @AdrianLarson I've added in the VF Page and full error. Do all the Product2 records need that field filled, or at least 1 or more? Dec 7, 2015 at 22:32
  • Which line is 55? All records would need that field populated. You want &&, not || on your blank checks, but the simpler approach would be to just use String.isNotBlank.
    – Adrian Larson
    Dec 7, 2015 at 22:54
  • 2
    this line: if(p.Industry__c != null || p.Industry__c != '') should be if (!String.isBlank(p.industry__c))
    – cropredy
    Dec 8, 2015 at 1:34

2 Answers 2

2

To me, it looks like you're never setting the industry value, which means the getUnconvertedProducts() method is returning null, which is causing the for (Product2 p :getUnconvertedProducts()) line in the GenerateAccountProducts() method to throw that exception.

Have you double checked the industry variable is actually being set?

1
  • It seems that the VF page was not setting it as intended. After just querying it and setting it the issue went away. Thanks! Dec 8, 2015 at 19:18
0

Looking through your code, the most obvious culprit is if any Product2 record you query for has an Industry__c of null, because then you would be calling null.split(';').

You can fix this by modifying your SOQL to include AND Industry__c != null.

1
  • I've added that, as well as an if statement to keep those from hitting it, and I am still getting the error. Dec 7, 2015 at 22:35

You must log in to answer this question.

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