2

I am pretty new to development and I am trying to user Chris Aldridge's Lightweight Trigger Framework http://chrisaldridge.com/triggers/lightweight-apex-trigger-framework/.

I am looking to create a task related to the lead that was edited if the field value changed. Below is something that I tried and it didn't work. There is also some code that is commented out because it didn't work or I was trying different variations.

Does someone know how it should be written?

public static void AfterUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems) {
      List<Task> newTasks = new List<Task>();

     for (Lead updatedLead : (List<Lead>) newitems.values())  { 
        //SObject oldLead = oldItems.get(updatedLead.Id);
        //SObject oldLeadValue = oldItems.values();
         //Lead oldLead = Trigger.oldMap.get(updatedLead.ID); 

        //check to see if the product interest has changed. only want to create a task if the product 
         interest has changed.
        if (updatedLead.ProductInterest__c != oldLead.ProductInterest__c)
           {
            //create a new task related to lead with product interest information
            Task newTask = new Task(
                Subject = 'Follow up with Lead, their Product Interest was updated',
                Status = 'Not Started', 
                WhoId = updatedLead.Id,
                OwnerId = updatedLead.OwnerId,
                Priority = 'Normal');
            //add this new task sObject to our list of tasks
            newTasks.add(newTask);
      } 
    } //end for loop
    //insert the batch of new tasks into Salesforce
    Insert newTasks;
 } //end AfterUpdate method
1
  • Did you try Lead oldLead = (Lead)oldItems.get(updatedLead.Id); ? Sep 9, 2020 at 12:50

2 Answers 2

4

What you have is pretty close.

The general form of what you want is newRecord.field != oldRecord.field, it's just a matter of knowing how to access the values.

There are multiple approaches you could take...

Keeping things as generic SObjects

The trigger frameworks that I've seen pretty much all pass collections (i.e. a list, set, or map) of the generic SObject type. The reasons for that are out of scope of this question, but the important part is that when you're working with a generic SObject, you need to use .get('myField') to read the value of a field instead of using simple dot-notation.

That would turn your if statement into this

if (updatedLead.get('ProductInterest__c') != oldLead.get('ProductInterest__c'))

Type-casting to a more specific SObject Type

Yeah, we can use generic SObjects just fine, but it's usually nicer to work on a specific SObject type (like Lead or Account).

The type system in Apex has some issues, but you should be able to do an explicit "type-cast" to change the type of your data from SObject to Lead.

When you type-cast from a generic type to a more specific type, that's called down-casting (as opposed to the opposite, going from a more specific type to a more generic type, which is up-casting). It isn't possible to do that (down-casting) in every situation, but it should be possible to do here.

Working on a more specific type allows you to use regular 'ol dot notation (myRecord.myField == 'some value') and gives you a bit more safety (as a quick example, you'll be warned about trying to put a Lead into a List<Account> when you try to save/deploy your code. If you were using a generic SObject, you might not encounter an error until you (or someone else) runs your code).

The change you'd need to make for this would be something like

// note that we're doing an explicit cast of the result we get from the oldItems map
Lead oldLead = (Lead)oldItems.get(updatedLead.Id);
1
  • thanks for the really clear explanation. I'm glad I wasn't too far off :) I tried the first part with my code and it worked: for (Lead updatedLead : (List<Lead>) newitems.values()) { SObject oldLead = oldItems.get(updatedLead.Id); if (updatedLead.get('ProductInterest__c') != oldLead.get('ProductInterest__c'))
    – LMills
    Sep 9, 2020 at 14:24
1

just iterate on the new Items doing gets on the old Items. I recommend adjusting types at the beginning of the code, in case you need to use the information again later on

public static void AfterUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems) {
    
    Map<Id, Lead> mpNewLead = (Map<Id, Lead>)newItems;
    Map<Id, Lead> mpOldLead = (Map<Id, Lead>)oldItems;
    List<Task> newTasks = new List<Task>();
    
    for(Lead updatedLead : mpNewLead.values()){
        ifif(updatedLead.ProductInterest__c != mpOldLead.get(updatedLead.Id).ProductInterest__c){
            Task newTask = new Task(
                Subject = 'Follow up with Lead, their Product Interest was updated',
                Status = 'Not Started', 
                WhoId = updatedLead.Id,
                OwnerId = updatedLead.OwnerId,
                Priority = 'Normal'
            );
            newTasks.add(newTask);
        }
    }
    Insert newTasks;
 }
2
  • HI Pedro, that almost worked. I had to change if(updatedLead.ProductInterest__c != oldItems.get(updatedLead.Id).ProductInterest__c){ to if(updatedLead.ProductInterest__c != mpOldLead.get(updatedLead.Id).ProductInterest__c){ can you update your code so I can mark it as the correct answer? Thanks for your help :)
    – LMills
    Sep 9, 2020 at 13:39
  • Hi, LMills. Kind of you to mention. Sorry for the map name. Glad I could help Sep 11, 2020 at 15:16

You must log in to answer this question.

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