3

I'm pretty new to apex and trying to create a trigger that will update a custom object field when a lead is converted. I think I'm close with the trigger, but I'm getting an error that my list "lstHandoff" doesn't exist. Any ideas?


trigger MoveHandoffOnLeadConvert on Lead (after update) {

    if (Trigger.isAfter) {

        if (Trigger.isUpdate) { 

            Set<ID> leadToContact = new Set<ID>();

            for (Lead ld : Trigger.new) {

                if(ld.isConverted && trigger.oldMap.get(ld.id).isConverted) continue; //only process newly converted leads

                if (ld.ConvertedContactId != null){                    

                    leadToContact.put(ld.ConvertedContactID);  

                }

            }

            if (!leadToContact.isEmpty()) {

                List<Handoff__c> lstHandoff = new List<Handoff__c>();

                for(Handoff__c handoffs:[select Id,Contact__c from Handoff__c where Lead__c in : leadToContact.keySet()]){

                    if(leadToContact.containsKey(handoffs.id)){

                        handoffs.Contact__c = leadToContact.get(handoffs.id);
                        lstHandoff.add(handoffs);

                    }

                }

            }

            if (!lstHandoff.isEmpty()) {

                Update lstHandoff;

            }

        }

    }

}
1
  • as the trigger is an after update - the tests for isAfter and isUpdate are irrelevant; the test for empty before the update lstHandoff is not required, if the list is empty, the DML statement becomes a NOP and doesn't count against DML calls
    – cropredy
    Commented Feb 12, 2015 at 21:06

2 Answers 2

2

Curly braces "{}" create "scope". You declared the scope of lstHandoff to be just within the if statement. The isEmpty check on that variable is outside the scope of that if statement, and therefore no longer exists. You could move the second if statement within the scope of the first, or move the variable declaration up one level of scope.

For general purposes, I usually recommend that all variable declarations are placed at the top of a function or trigger to avoid scope issues, but advanced developers will usually define a variable so it has the smallest scope possible so it can be garbage collected as soon as possible, to avoid excessive memory use (and possibly hitting the heap governor limit).

Edit:

Your trigger needs more help than just that. For example, you're calling keySet on a Set, which doesn't have a keySet method (because it is a set). Also, Lead__c wouldn't contain a Contact ID. That aside, you've also got some useless if statements (as noted elsewhere), and nonsensical if statements (Trigger.oldMap.get(ld.Id).IsConverted will never be true, because you can't modify a converted lead in any way that would generate a trigger evocation).

Here's a version that I'd use:

trigger MoveHandoffOnLeadConvert on Lead (after update) {
    Set<Id> contactIds = new Set<Id>(), leadIds = new Set<Id>();
    // Find all converted leads
    for(Lead record: Trigger.new) {
        if(record.IsConverted) {
            leadIds.add(record.Id);
        }
    }
    // return early if nothing to do
    if(leadIds.isEmpty()) {
        return;
    }
    // Get all handoffs for those leads
    Handoff__c[] handoffs = [SELECT Id, Lead__c FROM Handoff__c WHERE Lead__c IN :leadIds];
    // And associate with the new contact ID.
    for(Handoff__c record: handoffs) {
        record.Contact__c = Trigger.newMap.get(record.Lead__c).ConvertedContactId;
    }
    // Perform DML operation
    update handoffs;
}
1
  • Worked great.. thanks! Also, thanks for pointing out the errors in the code, I'm not used to apex, so I'm grateful for the guidance.
    – Matt
    Commented Feb 12, 2015 at 22:39
2

You need to instantiate your list outside of the IF() statement. When its only getting instantiated within an IF(), there are times when your IF() statement is false, and thus the list is never instantiated.

Then you use that list (that was never instantiated) in an IF statement, and its throwing an error.

When the IF() statement below returns false (your set of IDs is empty), then the list never gets instantiated

if (!leadToContact.isEmpty()) {

List<Handoff__c> lstHandoff = new List<Handoff__c>();
//More Code
//More Code

}

But you are still trying to use that list (which was never instantiated) later in this IF() statement. This is what I would suspect is causing the error

if (!lstHandoff.isEmpty()){    // 1stHandoff doesn't EXIST in this scenario
     //code
}

Something like this should fix it (just moved the instantiation of the list outside of the IF() statement.

List<Handoff__c> lstHandoff = new List<Handoff__c>();

if (!leadToContact.isEmpty()) {

     for(Handoff__c handoffs:[select Id,Contact__c from Handoff__c where Lead__c in : leadToContact.keySet()]){

           if(leadToContact.containsKey(handoffs.id)){
                 handoffs.Contact__c = leadToContact.get(handoffs.id);
                 lstHandoff.add(handoffs);
           }
      }
}

You must log in to answer this question.

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