0
map<Account, list< contact>> AccountContact = new map<Account, list< contact>>();
  
accountRecs = [SELECT Id, Name, Active_Contacts__c,(SELECT Id from CONTACTS WHERE Active__c = TRUE)  FROM Account WHERE Active_Contacts__c > 0 AND Id!=NULL]; 
    
for(account acc :accountRecs){
    if(!AccountContact.containskey(acc)){
        if(acc.contacts.size() > 0){
            accountContact.get(acc).Id; 

The fourth line from the for loop in my above code gives me Variable does not Exists Id. But I see Id is present in the Account object.

When I try with Name, then also, it is showing the same error. But these column names are present in the Account Object.

I am not sure if the above syntax is right. Can any one please help?

2
  • Hi Brindha, I don't see any logic of adding the values to the map AccountContact. As the map is null this is causing issue I guess Commented Dec 8, 2021 at 14:28
  • Thank you for the suggestion, But can you please help me with the correct syntax for the fourth line? It is saying Id does not exists. I will check and correct the logic afterwards. Commented Dec 8, 2021 at 14:36

2 Answers 2

2

This accountContact is a Map<Account, List< contact>>

So if you do accountContact.get(acc).Id; it will return you the List<Contact>. Which does not have direct Id, you need to loop in and get to Contact Id from that.

Note: Placing direct Account in key is not good approach. Replace that with AccountId instead.

2

Your code, as written, has several issues with it, but let's focus on the error first.

Explaining the error

You're getting this error because you're trying to get an Id from a List.

You define accountContact as a Map<Account, List<Contact>>, so when accountContact.get(acc) is evaluated, you get a List<Contact>.

The offending line of code, partially evaluated, is [an instance of List<Contact>].Id. Your code is trying to access the Id class variable of the List type, and List has no class variables.

The issues with your code

Using SObjects as the key in a Map (or as the type specified for a Set) can be useful, but is not something I'd recommend for beginners. Making any change to the instance of an object used as a key for a Map causes you to lose the ability to retrieve some data from the map.

A Map<Id, List<Contact>> would be more appropriate.

Your query has a useless filter in it Id != null. Any record that can be queried will have an Id. No exceptions.

Your query is filtering accounts with more than 0 active contacts, so the if(acc.contacts.size() > 0) check is redundant

Accessing child records (or the embedded list of child records like you do with acct.contacts.size()) directly carries some risk with it. Once you have a certain amount of child records, Salesforce would need to perform an internal call to queryMore() and then throw an exception. The safe way to access child records here is to have a nested loop.

e.g.

for(Account acct :myAccounts){
    List<Contact> safeList = new List<Contact>();

    for(Contact cont :acct.Contacts){
        safeList.add(cont);
    }
}

It's hard to tell exactly what you're trying to do with accountContact, but given that you have if(!accountContact.containsKey(...)) I assume you're trying to put data into the map.

The general pattern used to populate maps looks something like this:

Map<Id, List<ChildObject__c>> parentIdToChildren = new Map<Id, List<ChildObject__c>>();

for(Parent par :myParentList){
    // The general idea is to make sure that there will always be something in the map
    //   (that we can use) after this if() block
    // This tries to keep typing and repetition to a minimum, and allows us to skip
    //   the null checks that other approaches would need to do.
    if(!parentIdToChildren.containsKey(par.Id)){
        // By putting an empty list into the map (and not trying to immediately add
        //   the first record), the code to add the first record and the code to add
        //   all subsequent records becomes the same.
        // This allows us to avoid needing an ELSE block
        parentIdToChildren.put(par.Id, new List<ChildObject__c>());
    }

    for(ChildObject__c child :par.Children){
        // At this point, parentIdToChildren is guaranteed to have a non-null value
        //   stored for the map's key (the parent's Id)
        // Collections are stored in maps as references, so we can directly call .add()
        //   without needing to declare a temporary variable to hold the result of
        //   map.get(<key>)
        parentIdToChildren.get(par.Id).add(child);
    }
}

You must log in to answer this question.

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