8

I'm trying to implement the trigger framework outlined here:

The triggerhandler methods take lists or maps of sObjects as their inputs. In his example he casts list <sObject> as list <Account> by doing:

public void BeforeInsert(List<SObject> newItems) 
    {
        for (Account acc : (List<Account>)newItems)

What is the equivalent for:

public void AfterInsert(Map<Id, SObject> newItems) {
for (opporutnity opp: (........).values()
9

The .values() method will return a list of sObjects, which means that you can simply follow the same scenario and cast the list to a concrete sObject type:

for (Opportunity opp : (List <Opportunity>)newItems.values())

As long as all the values are of type "Opportunity" and you know that for sure.

The alternative way is to work with generic sObjects the whole time:

for (sObject opp : newItems.values())

Read more about dynamic apex

  • 4
    Actually, you can cast it only if the actual object contains a Map<Id, Opportunity>; if it's any other type, expect a runtime exception instead. You can't explicitly assign a Map<Id, SObject> to a Map<Id, Opportunity>, even if it's empty or only contains opportunities. – sfdcfox Jan 14 '16 at 0:22
  • @sfdcfox should I put the assignment in a try/catch block? – krewllobster Jan 14 '16 at 4:42
  • @krewllobster No, just make sure you're using the right type to begin with. Normally you'll know what object you're working on. That is one of the drawbacks of accepting a generic SObject list instead of a specific subtype. Just make sure that if you're in an opportunity trigger, you don't try to cast to a list of accounts or something, and you'll be fine. – sfdcfox Jan 14 '16 at 4:47
  • @sfdcfox I'm working on an 'after update' trigger and need to compare old and new values. I'm now feeling like I need to cast the opportunity lists, then rebuild two opportunity maps? Then I can say: for(opportunity o: newopps.values) {if(o.value != oldvalues.get(o.id).value) {logic}} – krewllobster Jan 14 '16 at 18:18
  • @krewllobster I have found that maps are relatively expensive compared to list access, so I'd recommend using Trigger.new/Trigger.old, and iterating over the values like this: for(Integer index = 0, size = Trigger.new.size(); index < size; index++) { Opportunity o = Trigger.old[index], n = Trigger.new[index]; if(n.value != o.value) { ... } }. – sfdcfox Jan 14 '16 at 18:50
1

I know this is old, but still pulls up as the result via a google search. So I'm going to post something I have had luck with.

If you know what sObject you are converting into, I've had success doing this:

objList //we'll say this is a Map<Id, sObject> where the sObject is an Opportunity
 List<Opportunity> oppList = objList.values();

Or looping:

   for(Opportunity o : objList.values())
   {
    //operations
   }

It's a little different than the previous answer given, so I hope someone finds it useful.

Edit: Apologies, realized this is for Map to Map. However I'll leave this because in some situations converting to a list from a Map will be beneficial as it should have already removed dups from being in a map, and then you can iterate through the list or perform DML on it.

0

You can iterate over a hash map using:

public void AfterInsert(Map<Id, SObject> newItems) {
    for (Id key: newItems.keySet())
    {
        Opportunity opp = (Opportunity)newItems.get(key);
        //do something with your opp
    }
}

So basically what you are doing here is:

  • using the keySet() method on the Map to get an iterator (so you're looping on the keys)
  • Then using that key, you get that particular SObject from your map (using the get() method)
  • Then you are type casting from SObject directly to an Opportunity class

There's an example here: Iterating over a map (Apex)

  • 5
    I would specifically avoid doing this: using a map when a list would suffice would waste about 25ms per item in the list. That's a pretty stiff penalty. – sfdcfox Jan 14 '16 at 0:24
  • Crikey. That's a heap. Poor heap. – Caspar Harmer Oct 2 '17 at 1:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.