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
Srikanth DorepalliSrikanth Dorepalli 

My task is to write a soql to fetch all the account records with corresponding contacts and create a map with account name as key and list of corresponding contacts as values

APEX CLASS:

public class fetch1 {
    public list<account> acc{set;get;}
    public map<string,list<contact>> mp{set;get;}
    public fetch1(){
        acc=[select name,(select lastname,firstname from contacts) from account ];
        list<contact> con=new list<contact>();
        mp=new map<string,list<contact>>();
        for(account a:acc){
            for(contact c:a.contacts){
                con.add(c);
                 }
            mp.put(a.name,con);
        }
        }
        }

VF:

<apex:page controller="fetch1" >
    <apex:form >
    <apex:pageBlock >
       <apex:pageBlockTable value="{!acc}" var="a">
        <apex:column headerValue="ACCOUNTS" value="{!a.name}"/>
           <apex:column headerValue="RELATED CONTACTS" >
               <apex:pageBlockTable value="{!mp}" var="cont">
               <apex:column value="{!mp[cont].firstname}"/>
                   <apex:column value="{!mp[cont].lastname}"/>
               </apex:pageBlockTable>
           </apex:column>
        </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

ERROR:
There are no errors in code.But when i am going for a preview of vf page i am getting this error "Incorrect parameter type for subscript. Expected Number, received Text "

 
Best Answer chosen by Srikanth Dorepalli
Gulshan Raj 4Gulshan Raj 4
Hi Srikanth,

I found two issues:
1)  The list of contact should be re-initialize, otherwise it will keep adding previous contacts
public fetch1(){
        acc=[select name,(select lastname,firstname from contacts) from account ];
        list<contact> con;
        mp=new map<string,list<contact>>();
        for(account a:acc){
			// Re-initialize contact list
            con=new list<contact>();
            for(contact c:a.contacts){
                con.add(c);
                 }
            mp.put(a.name,con);
      }
}

2)   Declaring "{!mp[cont].firstname}" in <apex:column value="{!mp[cont].firstname}"/>, is incorrect because "mp[cont]" actually returns list of contacts. Therefore List<Contact>.firstname throws exception.

Here we go complete correct code :

Apex Controller:
public class fetch1 {
    public list<account> acc{set;get;}
    public map<string,list<contact>> mp{set;get;}
    public fetch1(){
        acc=[select name,(select lastname,firstname from contacts) from account ];
        list<contact> con;
        mp=new map<string,list<contact>>();
        for(account a:acc){
            con=new list<contact>();
            for(contact c:a.contacts){
                con.add(c);
                 }
            mp.put(a.name,con);
        }
      }
  }

VF page:
<apex:page controller="fetch1" >
    <apex:form >
    <apex:pageBlock >
       <apex:pageBlockTable value="{!acc}" var="a">
        <apex:column headerValue="ACCOUNTS" value="{!a.name}"/>
           <apex:column headerValue="RELATED CONTACTS" >
               <apex:pageBlockTable value="{!mp[a.name]}" var="cont">
               <apex:column value="{!cont.firstname}"/>
                   <apex:column value="{!cont.lastname}"/>
               </apex:pageBlockTable>
           </apex:column>
        </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>


Thanks
Gulshan Raj

All Answers

Gulshan Raj 4Gulshan Raj 4
Hi Srikanth,

I found two issues:
1)  The list of contact should be re-initialize, otherwise it will keep adding previous contacts
public fetch1(){
        acc=[select name,(select lastname,firstname from contacts) from account ];
        list<contact> con;
        mp=new map<string,list<contact>>();
        for(account a:acc){
			// Re-initialize contact list
            con=new list<contact>();
            for(contact c:a.contacts){
                con.add(c);
                 }
            mp.put(a.name,con);
      }
}

2)   Declaring "{!mp[cont].firstname}" in <apex:column value="{!mp[cont].firstname}"/>, is incorrect because "mp[cont]" actually returns list of contacts. Therefore List<Contact>.firstname throws exception.

Here we go complete correct code :

Apex Controller:
public class fetch1 {
    public list<account> acc{set;get;}
    public map<string,list<contact>> mp{set;get;}
    public fetch1(){
        acc=[select name,(select lastname,firstname from contacts) from account ];
        list<contact> con;
        mp=new map<string,list<contact>>();
        for(account a:acc){
            con=new list<contact>();
            for(contact c:a.contacts){
                con.add(c);
                 }
            mp.put(a.name,con);
        }
      }
  }

VF page:
<apex:page controller="fetch1" >
    <apex:form >
    <apex:pageBlock >
       <apex:pageBlockTable value="{!acc}" var="a">
        <apex:column headerValue="ACCOUNTS" value="{!a.name}"/>
           <apex:column headerValue="RELATED CONTACTS" >
               <apex:pageBlockTable value="{!mp[a.name]}" var="cont">
               <apex:column value="{!cont.firstname}"/>
                   <apex:column value="{!cont.lastname}"/>
               </apex:pageBlockTable>
           </apex:column>
        </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>


Thanks
Gulshan Raj
This was selected as the best answer
Rohit B ☁Rohit B ☁
Hi Srikanth,
Here is the more optimized controller:-
public class fetch1 {
    public list<account> acc{set;get;}
    public map<string,list<contact>> mp{set;get;}
    public fetch1(){
        acc=[select name,(select lastname,firstname from contacts) from account];
        mp = new map<string,list<contact>>();
        for(account a : acc){
            mp.put(a.name, a.Contacts);
        }
    }
}

If you are not using "acc" on your VF page then you can eliminate this as well like this:-
public class fetch1 {
    public map<string,list<contact>> mp{set;get;}
    public fetch1(){
        mp = new map<string,list<contact>>();
        for(account a : [select name,(select lastname,firstname from contacts) from account]){
            mp.put(a.name, a.Contacts);
        }
    }
}

Hope it helps :)
Srikanth DorepalliSrikanth Dorepalli
Thank you Gulshan Raj  and Rohit B for your response.