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
barfsurferbarfsurfer 

Moving controller method to separate class

I have a successfully working controller and VF page.  Part of the reason for this controller was to bypass sharing rules.  BUT,  I need one of the methods in this controller to run with sharing.  So, I essentially created a standalone "with sharing" class with 1 method that does the querying, and returns the list of accounts back to the main controller.

 

Here's the original controller method that works:

 

    public List<aAccount> getSTAccounts(){
        if (STaccountList == null){
                STaccountList = new List<aAccount>();
                //This  query returns all site accounts in the hierarchy of the opp account where Ship To = True
                for(Account a : [Select id, Site_Number__c, Name, BillingStreet, BillingState, BillingCity From Account where 
                              parentid =:ApexPages.currentPage().getparameters().get('parentid') and Active_Ship_To__c = true Order by BillingCity, BillingStreet]){
                              STaccountList.add(new aAccount(a)); 
                              }                                                      
        }
        return STaccountList;
    }

All I really need to do is execute the above query with sharing rules in place.  So here's my standalone class:

 

public with sharing class multiShipToUtility {
/*
This little utility class is part of the whole BMI multi-bill to ship-to picker app.
For selecting the ship to sites, we need that list to be driven by sharing rules.  
In the bill to selection, we want the user to be able to see ALL bill to sites, regarless of territory
But for ship tos, we want that to be driven by territory assignment.  
To accomplish both, I had to break out the ship to selection into a separate class with sharing.
*/     
     
     public  static List<Account> getSTAccounts(string stParentId){
                string stID = stparentId;
                List<Account> STaccountList = new List<Account>();
                //This  query returns all site accounts in the hierarchy of the opp account where Ship To = True
                for(Account a : [Select id, Site_Number__c, Name, BillingStreet, BillingState, BillingCity From Account where 
                              parentid =: stParentId and Active_Ship_To__c = true Order by BillingCity, BillingStreet]){
                              STaccountList.add(a); 
                              }                                                      

        return STaccountList; 
     } 
}

 

So, back to the  main controller, I re-wrote the method like this:

 

    public List<aAccount> getSTAccounts(){

        if (STaccountList == null){
        string stParentID = ApexPages.currentPage().getparameters().get('parentid');
        List<Account> shipTos = new List<Account>();
        shipTos = multiShipToUtility.getSTAccounts(stParentID);
        for (Account a: shipTos){
        	STaccountList.add(new aAccount(a));
        }

       
        return STaccountList;    
        }

 

 

This won't compile with the message Non-void method might not return a value or might have statement after a return statement".

I researched this error a bit, and then added a basic else clause to the if-block above to return an empty list.  This compiles, but then blows up when I run the page:  "Attempt to de-reference a null object"

 

I also tried removing the static keyword from the method, but that doesn't compile eiter. 

 

So I'm totally stuck now.  Can anyone offer any suggestions? 

 

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
dnakonidnakoni

Again, in your multiBillToController class:

 

 

 if (STaccountList == null){
.
.
.
.
       		 for (Account a: shipTos){
        		STaccountList.add(new aAccount(a));

 You enter the IF when the STaccountList is null and then you are trying to add a new Account to it, that's probably why you are getting the null pointer exception.

 

try doing 

 

 

if (STaccountList == null){
    STaccountList = new List<Account>();

 

 

 

All Answers

dnakonidnakoni

Could it be because you are doing this:

 

 

STaccountList.add(new aAccount(a));

 

 

Without instantiating the List first? E.g.:

 

 

STaccountList = new List<Account>();

STaccountList.add(new aAccount(a));

 I see you had it in the original class but not in the separate one.

 

Dan

 

 

 

michaelforcemichaelforce

How are you initiating 'STaccountList'?  My instincts tell me that IF statement might not be running when it should... try changing it to:

 

 

if(STaccount.size()>0){

 

 

Kevin SwiggumKevin Swiggum

 

It looks like the controller method is missing an end curly bracket....to close out the IF statement. By putting the curly bracket after the for loop, your method will always return the STaccountList. See below. 

 

 

public List<aAccount> getSTAccounts(){

        if (STaccountList == null){
             string stParentID = ApexPages.currentPage().getparameters().get('parentid');
             List<Account> shipTos = new List<Account>();
             shipTos = multiShipToUtility.getSTAccounts(stParentID);
             for (Account a: shipTos){
        	     STaccountList.add(new aAccount(a));
             } 
	}   //End IF
       
        return STaccountList;    
  }
TehNrdTehNrd

You have parentheses in wrong spots. Try this:

 

 

public List<aAccount> getSTAccounts(){
	if(STaccountList == null){
		string stParentID = ApexPages.currentPage().getparameters().get('parentid');
		List<Account> shipTos = new List<Account>();
		shipTos = multiShipToUtility.getSTAccounts(stParentID);
		
		for (Account a: shipTos){
			STaccountList.add(new aAccount(a));
		}
	}
	return STaccountList; 
}

 

 

barfsurferbarfsurfer

Thanks guys!  Still not working though.  Putting the return statement inside the IF block was dumb, and I figured that would do the trick as well.   The controller compiles now, but the page bombs when I load with the error "Attempt to de-reference a  null object". What the hell does that mean?   I saw this before in some of my other feeble attempts to solve. Arrgh!  :smileysad:

 

So here's what I've got now:

 

    public List<aAccount> getSTAccounts(){
//aAccount is just a wrapper class of an account and a checkbox for selection by user
        if (STaccountList == null){
        string stParentID = ApexPages.currentPage().getparameters().get('parentid');
        List<Account> shipTos = new List<Account>();
        shipTos = multiShipToUtility.getSTAccounts(stParentID);
        for (Account a: shipTos){
        	STaccountList.add(new aAccount(a));
        }

       
            
        }
      return STaccountList;
    }

 

 

barfsurferbarfsurfer

Just re-posting full code in case that's helpful!

public class multiBillToController {
    public List<aAccount> accountList {get; set;}
    public List<aAccount> STaccountList {get; set;}
    public List<AccountPartner> partnerList {get; set;}
    public List<aAccount> getSTAccounts(){

        if (STaccountList == null){
        string stParentID = ApexPages.currentPage().getparameters().get('parentid');
        List<Account> shipTos = new List<Account>();
        shipTos = multiShipToUtility.getSTAccounts(stParentID);
        for (Account a: shipTos){
        	STaccountList.add(new aAccount(a));
        }

       
            
        }
      return STaccountList;
    }

 

public with sharing class multiShipToUtility {
/*
This little utility class is part of the whole BMI multi-bill to ship-to picker app.
For selecting the ship to sites, we need that list to be driven by sharing rules.  
In the bill to selection, we want the user to be able to see ALL bill to sites, regarless of territory
But for ship tos, we want that to be driven by territory assignment.  
To accomplish both, I had to break out the ship to selection into a separate class with sharing.
*/     
     
     public  static List<Account> getSTAccounts(string stParentId){
                string stID = stparentId;
                List<Account> STaccountList = new List<Account>();
                //This  query returns all site accounts in the hierarchy of the opp account where Ship To = True
                for(Account a : [Select id, Site_Number__c, Name, BillingStreet, BillingState, BillingCity From Account where 
                              parentid =: stParentId and Active_Ship_To__c = true Order by BillingCity, BillingStreet]){
                              STaccountList.add(a); 
                              }                                                      

        return STaccountList; 
     } 
}

 

 

 

 

Kevin SwiggumKevin Swiggum

Is it telling you where it's failing? A line number? The null error is basically telling you that you're trying to run a method on a null object. Just for grins, you could try putting the following if block around your for loop. It's also possible that the constructor on your aAccount class is experiencing a null value on the account getting passed in....maybe on a field that isn't visible within a sharing context??

 

    public List<aAccount> getSTAccounts(){
//aAccount is just a wrapper class of an account and a checkbox for selection by user
        if (STaccountList == null){
        string stParentID = ApexPages.currentPage().getparameters().get('parentid');
        List<Account> shipTos = new List<Account>();
        shipTos = multiShipToUtility.getSTAccounts(stParentID);
        if (shipTos.size() > 0) {
             for (Account a: shipTos){
        	     STaccountList.add(new aAccount(a));
             }
        }

       
            
        }
      return STaccountList;
    }
dnakonidnakoni

Again, in your multiBillToController class:

 

 

 if (STaccountList == null){
.
.
.
.
       		 for (Account a: shipTos){
        		STaccountList.add(new aAccount(a));

 You enter the IF when the STaccountList is null and then you are trying to add a new Account to it, that's probably why you are getting the null pointer exception.

 

try doing 

 

 

if (STaccountList == null){
    STaccountList = new List<Account>();

 

 

 

This was selected as the best answer
barfsurferbarfsurfer

dnakoni, you were right!!  Thanks so much everyone for helping out.  I knew it was something stupid and easy. 

 

Here's working method for reference:

 

    public List<aAccount> getSTAccounts(){

        if (STaccountList == null){
        STaccountList = new List<aAccount>();
        string stParentID = ApexPages.currentPage().getparameters().get('parentid');
        List<Account> shipTos = new List<Account>();
        shipTos = multiShipToUtility.getSTAccounts(stParentID);
        for (Account a: shipTos){
        	STaccountList.add(new aAccount(a));
        }

       
            
        }
      return STaccountList;
    }