Invalid initializer type List found for Map

1.3K    Asked by CarolineBrown in Salesforce , Asked on Apr 16, 2021

 I am new into apex development. I am getting an this error in my map:

Invalid initializer type List found for Map expected a Map with the same key and value types, or a valid SObject List

Why do I get this invalid initializer c error? How can I fix it?

Here is the code:

Trigger LastOnsiteVisit_SA on Event(Before insert, before update) { Set eventIds = new Set(); Set AccountIDZ = new Set(); for (Event evt: Trigger.New) { eventIds.add(evt.Id); AccountIDZ.add(evt.AccountId); } Set Accountset = new Set([SELECT ID FROM Account where ID IN: AccountIDZ]); Map mp2 = new Map ([SELECT AccountId, EndDateTime FROM Event WHERE RecordTypeId = '01270000000YSks' AND AccountId IN :AccountIDZ AND Type = 'Onsite Meeting' ORDER BY EndDateTime DESC]); for (Account acct: Accountset) { if (mp2.containskey(acct.id)) { acct.Last_Onsite_Visit__c = mp2.get(acct.Id).Date(); } } }


Answered by Guy Rodd

You can create this trigger functionality without writing a single line of code if you just install the Declarative Lookup Rollup Summaries tool and configure the corresponding Lookup Rollup Summary.


The closest constructor which would be valid is to use new Map(List). That would look like:

Map events = new Map([/*query*/]);

This constructor will map each record by its own Id. If you want to map each AccountId to the corresponding EndDateTime, you will have to roll your own map. Note that there can be multiple records matching the same key, so you have to decide whether you want to just clobber the results, get the most recent value, etc.

A typical pattern for doing the mapping yourself would be:

Map> times = new Map>(); for (Event record : [/*query*/]) { if (!times.containsKey(record.AccountId)) times.put(record.AccountId, new List()); times.get(record.AccountId).add(record.EndDateTime); }

You could also use a clever aliasing trick to, for example, get the most recent timestamp for each AccountId:

Map mostRecent = new Map([ SELECT AccountId Id, MAX(EndDateTime) EndDateTime FROM Event WHERE ... ]);

With this map in hand, you will consume much less CPU time getting the data you need. Note also that you do not need to query for a record to update it. If you already know its Id, you can just construct a record with that Id and you're good to go.

List accounts = new List(); for (Id accountId : mostRecent.keySet()) { accounts.add(new Account( Id=accountId, MyDateField__c=mostRecent.get(accountId).get('EndDateTime') )); } update accounts;

If you get a chance, you should look at best practices around error handling and logic-less trigger bodies (using a trigger handler pattern).



Your Answer

Interviews

Parent Categories