In continuation of our previous post Learning Apex Triggers (Part1), this guide will provide use cases. It will also provide examples for each trigger event. It is part of the “Learning Apex Triggers” series.
Salesforce triggers are small pieces of code that run automatically when records change in Salesforce. They let you add custom logic before or after data is inserted, updated, deleted, or even restored (undeleted). Triggers can set default values, enforce business rules, update related records, or send notifications based on your company’s needs.
In Salesforce there are below seven trigger events-
- Before Insert
- Before Update
- Before Delete
- After Insert
- After Update
- After Delete,
- After Undelete
Before Insert Trigger
A Before Insert trigger runs just before a new record is saved to the database. This means you can examine or change the record’s data before Salesforce stores it. Use a before-insert trigger when you want to fill in missing values or enforce rules on new records. Because the trigger runs early, you can set default fields or stop bad data from being saved.
- When to use: Setting or checking fields on a new record before it’s saved. This is good for default values or initial validation.
- Key idea: You get access to the new records via
Trigger.newand can change their fields.
Examples Use Cases:
- If a new Opportunity is created without a Stage, set a default Stage (like Prospecting).
- When a Lead is inserted, require that an email address is provided (or fill a default placeholder).
- Setting the initial Case Status to “New” if it is blank on creation.
trigger SetDefaultStage on Opportunity (before insert) {
for (Opportunity opp : Trigger.new) {
// If Stage is not set on a new opportunity, default it to 'Prospecting'
if (opp.StageName == null) {
opp.StageName = 'Prospecting';
}
}
}
In this code, before any new Opportunity is saved, we check if its StageName is empty. If it is, we set it to “Prospecting.” Because this is a before insert trigger, the change is made before the record is written to the database.
Before Update Trigger
A Before Update trigger runs right before an existing record is updated (saved) in the database. Use it to check or modify data before the update happens. This is useful for validating changes, blocking illegal updates, or adjusting fields based on new information.
- When to use: Checking or fixing data just before a record is updated. Good for enforcing rules or automatically setting fields on update.
- Key idea: You have access to
Trigger.new(the new values) andTrigger.old/Trigger.oldMap(the old values) to compare changes.
Examples Use Cases:
- If an Opportunity is changed to Stage “Closed Won”, check if the Close Date is empty. If it is, set the Close Date to today’s date.
- Do not allow discounts to be set too high. If someone tries to update the Opportunity Amount to over $100,000, show an error and block the update.
- When a Contact’s email is updated, trim extra spaces or enforce a proper format before saving.
Code Example:
trigger SetCloseDate on Opportunity (before update) {
for (Opportunity opp : Trigger.new) {
// If stage is changed to Closed Won and CloseDate is blank, set it to today
if (opp.StageName == 'Closed Won' && opp.CloseDate == null) {
opp.CloseDate = Date.today();
}
}
}
In this before update trigger, we check each updated Opportunity. If its stage is updated to “Closed Won”, we set the Close Date to today if it doesn’t have one. This action happens automatically. This change happens before saving the updated record.
Before Delete Trigger
A Before Delete trigger runs right before a record is deleted from the database. It cannot change the record (since it’s about to be gone) but it can prevent deletion or perform checks. Use a before-delete trigger to stop deletion under certain conditions.
- When to use: Validating deletion or stopping it if business rules require.
- Key idea: You access the records being deleted via
Trigger.old(because they no longer have new values) and can calladdError()to block the delete.
Examples Use Cases:
- Prevent deleting an Opportunity if its Amount is over $100,000.
- Do not allow the deletion of an Account if it has open Cases. Avoid deletion if it has important data, such as when a custom “Critical_Account” field is true.
- Check if a Case with status “Escalated” is about to be deleted, and stop it to protect critical issues.
Code Example:
trigger PreventHighValueDeletion on Opportunity (before delete) {
for (Opportunity opp : Trigger.old) {
// Prevent deleting an Opportunity worth more than $100,000
if (opp.Amount != null && opp.Amount > 100000) {
opp.addError('Cannot delete high-value opportunities.');
}
}
}
Here, we loop over each Opportunity being deleted (Trigger.old) and if its Amount is greater than 100,000, we call addError(). This stops the deletion and shows an error message to the user.
After Insert Trigger
An After Insert trigger runs right after new records have been saved to the database. By this point, each new record has a Salesforce ID. Use after-insert triggers to do things that require the record to exist first, like creating related records or sending notifications. You cannot change the fields of the just-inserted record directly (you can only change other records or do further actions).
- When to use: Performing actions that need the new record’s ID or have side effects.
- Key idea: The record is already saved. Use this to create related records, send emails, or update other objects. Access the new records via
Trigger.new.
Examples Use Cases:
- After a new Account is created, automatically create a welcome Task or Contact associated with that Account.
- When a new Lead is inserted, send a notification email to the sales rep or assign it to a queue.
- After inserting a new Opportunity, update inventory levels by subtracting the ordered quantity from a product stock record.
Code Example:
trigger CreateFollowUpTask on Opportunity (after insert) {
List<Task> tasksToAdd = new List<Task>();
for (Opportunity opp : Trigger.new) {
Task t = new Task();
t.WhatId = opp.Id; // relates task to the opportunity
t.Subject = 'Follow up on opportunity';
t.Status = 'Not Started';
tasksToAdd.add(t);
}
if (!tasksToAdd.isEmpty()) {
insert tasksToAdd;
}
}
This after insert trigger creates a new Task for each newly inserted Opportunity. Because it runs after insert, each Opportunity has an Id we can use as WhatId on the Task. We collect all tasks in a list and insert them at once.
After Update Trigger
An After Update trigger runs just after existing records have been updated. Use it to react to changes by updating other records or sending notifications. Since the updates are committed, you typically use after-update to change related records or perform extra logic. You still have Trigger.new and Trigger.old to see what changed.
- When to use: Making updates to other records after a save, or responding to changes.
- Key idea: The updated record already exists. Use this to touch related objects or log changes. You can compare
Trigger.newandTrigger.oldto detect specific changes.
Examples Use Cases:
- If an Opportunity stage changes to “Closed Won,” update the parent Account’s total closed deals. Alternatively, add the amount to a summary field.
- When a Case status is changed to “Closed,” create a follow-up Task or send a closure email to the customer.
- After updating a Product’s price, recalculate the total for all related Orders or Opportunities.
Code Example:
trigger NotifyOnCaseClose on Case (after update) {
for (Case c : Trigger.new) {
// If a Case is now Closed (status changed), create a completion task
if (c.Status == 'Closed') {
Task t = new Task(
WhatId = c.Id,
Subject = 'Case closed',
Status = 'Completed'
);
insert t;
}
}
}
In this after update trigger, for each Case that is now closed, we insert a new completed Task. This could be used to notify someone or record that the case was closed. (In a real scenario, you might check Trigger.oldMap to only do this when the status changed to Closed, but this simple example shows the basic idea.)
After Delete Trigger
An After Delete trigger runs right after records have been deleted. Use it to clean up or update any related data because the original record is gone. The records have been removed from the database. However, you can still see their old values in Trigger.old.
- When to use: Cleaning up or updating other data after a delete.
- Key idea: Use
Trigger.oldto know what was deleted. You might delete related child records or update summary fields on parent records.
Examples Use Cases:
- If an Account is deleted, delete any related Contacts or custom child records that Salesforce didn’t automatically remove.
- After a Campaign is deleted, update a dashboard or notify marketing managers that it was removed.
- If an Inventory record is deleted, set a flag on a related Product or log the deletion for auditing.
Code Example:
trigger DeleteRelatedContacts on Account (after delete) {
// Find all contacts whose Account was deleted
List<Contact> relatedContacts = [SELECT Id FROM Contact WHERE AccountId IN :Trigger.oldMap.keySet()];
if (!relatedContacts.isEmpty()) {
delete relatedContacts;
}
}
This after delete trigger looks up Contacts whose AccountId was in the set of deleted Accounts (Trigger.oldMap.keySet()). It then deletes those Contacts. (In many orgs, Contacts are automatically deleted when an Account is deleted, but this example shows how to clean up related data if needed.)
After Undelete Trigger
An After Undelete trigger runs after records are restored from the Recycle Bin (i.e., when a user undeletes them). This is a special trigger event. Use it when you want to reinitialize or update data related to the revived record. Only records of objects that support undelete (like Accounts, Contacts, etc.) will fire this trigger.
- When to use: Adjusting data or notifying users when a record is brought back.
- Key idea: Treat the record as “new again,” but keep in mind it had past data. Use
Trigger.newto see the restored records.
Examples Use Cases:
- If a Contact is undeleted, add the Contact back to an email campaign or reassign it to a user.
- When an Account is undeleted, set a custom “Status” field back to “Active” or notify the record owner.
- If a Custom Object record is undeleted, rebuild any related lookup or summary fields that might have been cleared.
Code Example:
trigger ReactivateTasksOnContactUndelete on Contact (after undelete) {
List<Task> tasksToAdd = new List<Task>();
for (Contact c : Trigger.new) {
Task t = new Task(
WhatId = c.Id,
Subject = 'Contact was restored',
Status = 'Not Started'
);
tasksToAdd.add(t);
}
if (!tasksToAdd.isEmpty()) {
insert tasksToAdd;
}
}
This after undelete trigger creates a new Task for each restored Contact. It might be used to notify someone that the Contact record was recovered. Because the trigger is after undelete, the Contact records are already active again and have their IDs.


Leave a comment