0

I am new to apex and have wrote a trigger on the lead object that updates fields on the record, and also creates tasks associated with the record.

I have set up the code for both of these requirements to the best of my ability but am stuck on the appropriate use of 'before/after' in the trigger.

How do I structure the code to incorporate both the before and after aspect of this requirement. Here is what I have so far.

trigger KeyFieldsPopulated on Lead (before insert, before update) {
    for (Lead l : Trigger.New) {
        //Create list to store key fields 
        List<String> KeyFields = new List<String>();
        KeyFields.add(l.FirstName);
        KeyFields.add(l.LastName);
        KeyFields.add(l.Email);
        KeyFields.add(l.Phone);
        KeyFields.add(l.Website);
        KeyFields.add(l.Title);

        //Create list to store key fields that have a value
        List<String> KeyFieldsPopulated = new List<String>();

        //Create a counter variable to track how many key fields have a value
        Integer counter = 0;

        //Loop through the key fields 
        for (Integer i = 0; i<KeyFields.size(); i++) {
            if (KeyFields[i]!=null) {
                KeyFieldsPopulated.add(KeyFields[i]);
                counter = counter + 1; 
            }
            l.Key_Fields__c = counter;
        }

        //Loop through the populated key fields and create a task
        if (counter >= 3) {
            for (Integer j = 0; j < KeyFieldsPopulated.size(); j++) {
                Task t = new Task();
                t.Subject = 'Verify the '+ KeyFieldsPopulated[j] + ' field';
                t.WhatId = l.Id;
            }
        }
    }
}

1 Answer 1

0

An easy discriminant (not comprehensive, but a first pass that applies here) is "Do I need a Record Id for what I'm trying to do?" If the answer is yes, the functionality belongs in an after trigger, because the records in Trigger.new don't receive Salesforce Ids until the after stage.

So here:

    //Loop through the populated key fields and create a task
    if (counter >= 3) {
        for (Integer j = 0; j < KeyFieldsPopulated.size(); j++) {
            Task t = new Task();
            t.Subject = 'Verify the '+ KeyFieldsPopulated[j] + ' field';
            t.WhatId = l.Id;
        }

  }

you need to be in after context, because what you're doing requires the l.Id field to be populated in order to create a related object.

Conversely, this code

for (Integer i = 0; i<KeyFields.size(); i++) {
    if (KeyFields[i]!=null) {
        KeyFieldsPopulated.add(KeyFields[i]);
        counter = counter + 1;

    }
    l.Key_Fields__c = counter;
}

belongs in before context, because you're mutating fields on the object based on other fields that are populated at the time of insertion. You don't need an Id for that, and when you do so in before context, you don't need to perform DML and incur the possibility of trigger recursion.

I would strongly encourage you to consider a trigger handler framework pattern here. When working with multiple trigger events, it often becomes difficult to follow and to debug the logic when it's all in the trigger body. Adopting a good trigger framework (there are many available in the world of Salesforce blogs and in GitHub) helps you keep these events cleanly separated from one another by factoring your logic out into a clean, testable trigger handler class.

1
  • Thanks David, I'll do some googling to see what's out there. Commented Mar 31, 2020 at 13:32

You must log in to answer this question.

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