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
Nitin LedangeNitin Ledange 

Hi Guys, I'm trying to display all the related contacts to all the related Accounts (Accounts are returned by a SOQL query when I input some name in VF Page nd it uses Like input% ). But I'm getting

Hi Guys, I'm trying to display all the related contacts to all the related Accounts (Accounts are returned by a SOQL query when I input some name in VF Page nd it uses Like 'input%' ). But I'm getting Visualforce Error  System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!find}' in component <apex:commandButton> in page passingvaluestocontroller: Class.aaPage52.find: line 24, column 1 Class.aaPage52.find: line 24, column 1 . 

Here's My Code : 
VF PAge : 
<apex:page controller="aaPage52">
<apex:form >
<apex:pageBlock title="Search" >
<apex:outputLabel for="searchString" value="Enter the Search String : ">
</apex:outputLabel>
<apex:inputText value="{!searchText}" id="searchString"/>
<apex:commandButton value="Find" action="{!find}" />
</apex:pageBlock>
<apex:pageBlock title="Results">
<apex:pageblockTable value="{!results}" var="r">
<apex:column value="{!r.name}"/>
<apex:column value="{!r.Phone}"/>
<apex:column value="{!r.Industry}"/>
</apex:pageblockTable>
</apex:pageBlock> 
<apex:pageBlock title="Contacts Related to this Account">
<apex:pageblockTable value="{!Contacts}" var="con">
<apex:column value="{!con.FirstName}"/>
<apex:column value="{!con.LastName}"/>
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

Controller : 

public class aaPage52 {
    List<Account> results;
    List<Contact> con;
    public String searchText { get; set; }    
    public List<Account> getResults() {
        return results;
    }    
    public List<Contact> getContacts() {
        return con;
    }
    
    public pageReference find(){
     results = [Select Name,Phone,Industry from Account where name LIKE :searchText+'%']; 
     If(results.size()!=0){
     List<contact> cont;
     for(Integer i=0; i< results.size(); i++){
       cont  = [Select FirstName, LastName from Contact where AccountID =:results[i].Id];       
     }
     con.addAll(cont);
     }
     update con;
     return null;
    }   
}

And Earlier when I didn't use con.addAll(cont); , I was able to Display the related Contacts  when Only one Account was returned by the Account Query. 


Appreciate your help.
Thanks,
Nitin Patil
Best Answer chosen by Nitin Ledange
Manish  ChoudhariManish Choudhari
Hi Nitin,

As the exception says, you are trying to access method on a null Object. In your code you have not initialized "con" variable or in other words the memory is not allocated to your "con" variable. Since the con variable does not exist in memory (or it is null), you cannot access any methods on it.
con = new List<Contact>();


Now, that is only syntax error. However as per best practice, you will soon get so many other exceptions (like Too Many Soql Queries) if you do not bulkify your code. As per Governer limits, you can only run 100 SOQL queries in a single transaction. In you code you are writing SOQL queries inside for loop based on total number of account result. If you have more than 99 account results from 1st query, you will see Too Many Soql Queries Exception and your transaction will fail.
Hence it is best practice to always bulkify your code and avoid writing SOQL inside for loop. You can avoid writing any extra query in this scenario by simply using Inner SOQL statement. You can use below code to achieve same functionality:
 
public class aaPage52 {
    List<Account> results;
    List<Contact> con;
    public String searchText { get; set; }    
    public List<Account> getResults() {
        return results;
    }    
    public List<Contact> getContacts() {
        return con;
    }
    
    public pageReference find(){
     results = [Select Name,Phone,Industry, (Select FirstName, LastName from Contacts)    from Account where name LIKE :searchText+'%']; 
     if(results.size()!=0){
          //initialize con variable here if it is null
          if(con == null){
              con = new list<Contact>();
          }
          // ForEach loop to loop through all results
          for(Account acc : results){
                con.addAll(acc.Contacts);
          }
    
     update con;
     return null;
    }   
}



Useful links:
https://help.salesforce.com/articleView?id=000181404&type=1
https://developer.salesforce.com/page/A_Deeper_look_at_SOQL_and_Relationship_Queries_on_Force.com

Let me know if any further help is needed on this one.

Thanks,
Manish

All Answers

Dushyant SonwarDushyant Sonwar
Hi Nitin ,

Your list variable con has to be initialized before you want to use it in your class i.e (allocating memory to the list object).
 
con = new list<contact>();

After some changes your code will be something like this below:
 
public class aaPage52 {
    List<Account> results;
    List<Contact> con;
    public String searchText { get; set; }    
    public List<Account> getResults() {
        return results;
    }    
    public List<Contact> getContacts() {
        return con;
    }
    
    public pageReference find(){
     results = [Select Name,Phone,Industry from Account where name LIKE :searchText+'%']; 
     If(results.size()!=0){
     List<contact> cont = new list<Contact>();
     con = new list<Contact>();
     for(Integer i=0; i< results.size(); i++){
       cont  = [Select FirstName, LastName from Contact where AccountID =:results[i].Id];       
     }
     con.addAll(cont);
     }
     update con;
     return null;
    }   
}

Hope this helps :) 

 
Manish  ChoudhariManish Choudhari
Hi Nitin,

As the exception says, you are trying to access method on a null Object. In your code you have not initialized "con" variable or in other words the memory is not allocated to your "con" variable. Since the con variable does not exist in memory (or it is null), you cannot access any methods on it.
con = new List<Contact>();


Now, that is only syntax error. However as per best practice, you will soon get so many other exceptions (like Too Many Soql Queries) if you do not bulkify your code. As per Governer limits, you can only run 100 SOQL queries in a single transaction. In you code you are writing SOQL queries inside for loop based on total number of account result. If you have more than 99 account results from 1st query, you will see Too Many Soql Queries Exception and your transaction will fail.
Hence it is best practice to always bulkify your code and avoid writing SOQL inside for loop. You can avoid writing any extra query in this scenario by simply using Inner SOQL statement. You can use below code to achieve same functionality:
 
public class aaPage52 {
    List<Account> results;
    List<Contact> con;
    public String searchText { get; set; }    
    public List<Account> getResults() {
        return results;
    }    
    public List<Contact> getContacts() {
        return con;
    }
    
    public pageReference find(){
     results = [Select Name,Phone,Industry, (Select FirstName, LastName from Contacts)    from Account where name LIKE :searchText+'%']; 
     if(results.size()!=0){
          //initialize con variable here if it is null
          if(con == null){
              con = new list<Contact>();
          }
          // ForEach loop to loop through all results
          for(Account acc : results){
                con.addAll(acc.Contacts);
          }
    
     update con;
     return null;
    }   
}



Useful links:
https://help.salesforce.com/articleView?id=000181404&type=1
https://developer.salesforce.com/page/A_Deeper_look_at_SOQL_and_Relationship_Queries_on_Force.com

Let me know if any further help is needed on this one.

Thanks,
Manish
This was selected as the best answer
Nitin LedangeNitin Ledange
Thanks guys. It's working