Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

Note:- Code is highlighted in a yellow background color.

27th June 2023

1. What is Trigger?

Trigger in Salesforce is essentially an Apex script used by developers before or after events
related to data manipulation language (DML). Apex triggers enable you to perform custom
actions before or after changes to Salesforce records, such as insertions, updates, or
deletions. Apex trigger gets executed when you perform a DML operation either from UI or
Apex.

2. How to create an Apex Trigger?

1st Way:-
In Developer Console → File → New → Apex Trigger → Write name of trigger
and select sObject.

2nd Way:-
Inside Object Manager → Select Object on which you want to create trigger
→ On the left pane select trigger → Click new button

3. Trigger Syntax

trigger TriggerName on ObjectAPIName (trigger_events) {


//code_block
}
4. Trigger events in salesforce?

A trigger is a set of statements that can be executed on the following events. In trigger
events, one or more of the below events can be used with comma-separated.
● before insert
● before update
● before delete
● after insert
● after update
● after delete
● after undelete

5. What are the different types of Triggers?

● Before triggers are used to perform a task before a record is inserted or updated or
deleted. These are used to update or validate record values before they are saved to
the database.
● After triggers are used if we want to use the information set by the Salesforce
system and to make changes in the other records. are used to access field values
that are set by the system (such as a record’s Id or LastModifiedDate field), and to
affect changes in other records. The records that fire the after the trigger is read-only.

6. What are context variables in triggers?

● isExecuting: Returns true if the current context for the Apex code is a trigger, not a
Visualforce page, a Web service, or an executeanonymous() API call.

● isInsert: Returns true if this trigger was fired due to an insert operation, from the
Salesforce user interface, Apex, or the API.

● isUpdate: Returns true if this trigger was fired due to an update operation, from the
Salesforce user interface, Apex, or the API.

● isDelete: Returns true if this trigger was fired due to a delete operation, from the
Salesforce user interface, Apex, or the API.

● isBefore: Returns true if this trigger was fired before any record was saved.

● isAfter: Returns true if this trigger was fired after all records were saved.
● isUndelete: Returns true if this trigger was fired after a record is recovered from the
Recycle Bin (that is, after an undelete operation from the Salesforce user interface,
Apex, or the API.)

● new: Returns a list of the new versions of the sObject records. This sObject list is
only available in insert, update, and undelete triggers, and the records can only be
modified in before triggers.

● newMap: A map of IDs to the new versions of the sObject records. This map is only
available in before update, after insert, after update, and after undelete triggers.

● old : Returns a list of the old versions of the sObject records. This sObject list is only
available in update and delete triggers.

● oldMap: A map of IDs to the old versions of the sObject records. This map is only
available in update and delete triggers.

● size: The total number of records in a trigger invocation, both old and new.

● operationType: Explained later.

7. What is Trigger.new vs Trigger.old vs Trigger.oldMap vs


Trigger.newMap?

Trigger.new always has new values of the record.


Trigger.old always has previous values of the record.

Both of the above have return type as List.


Look at the below code:-

trigger OpportunityTrigger on Opportunity (before update) {

List<Opportunity> newList = Trigger.new;


List<Opportunity> oldList = Trigger.old;

System.debug('newList : '+newList);
System.debug('oldList : '+oldList);
}

Trigger.newMap contains new values of record on value side and id on key side.
Trigger.oldMap contains old values of record on value side and id on key side.

Both of the above have return type of map. Please look at the below code:-
trigger OpportunityTrigger on Opportunity (before update) {

Map<Id, Opportunity> newMap = Trigger.newMap;


Map<Id, Opportunity> oldMAp = Trigger.oldMap;

System.debug('newMap : '+newMap);
System.debug('oldMAp : '+oldMAp);
}

8. Sizes:-

Trigger.new, Trigger,old, Trigger.oldMap and Trigger.newMap these collections have


a maximum of 200 records.

Assignment:-

1. Please practice everything including context variables deeply.


2. Practice on Trigger.new, Trigger.old, Trigger.newMap,
Trigger.oldMap by debugging their values in various trigger
events.
28th June 2023

1. Why there is no before undelete?

An update or Insert can have a Before functionality as the record exists.


Where as there is no Record before deleting the Actual record.
Hence only after deleting we can have the Undelete event, whereas every record merely
exists before deleting

2. What is Trigger.isExecuting?

If you are calling any apex class from trigger then Trigger.isExecuting returns true.
Suppose take a look at below class:-

OpportunityTrigger.apxt

trigger OpportunityTrigger on Opportunity (before update) {

OpportunityTriggerHelper.myMethod();
}

OpportunityTriggerHelper.apxc

public class OpportunityTriggerHelper {

public static void myMethod() {

if(Trigger.isExecuting) {
System.debug('Trigger Code');
} else {
System.debug('Non Trigger Code');
}
}
}

If OpportunityTriggerHelper.myMethod() is getting called from trigger then


System.debug('Trigger Code'); this part will get executed.
If OpportunityTriggerHelper.myMethod() is getting called from other than trigger
then System.debug('Non Trigger Code'); this part will get executed.
3. How to use Switch-when in Apex?

public class SwitchClass {

public static void cities(String cityName) {

if(cityName == 'Pune')
{
System.debug('I am inside pune');
}
else if(cityName == 'Nasik')
{
System.debug('I am inside Nasik');
}
else if(cityName == 'Mumbai')
{
System.debug('I am inside Mumbai');
}
else
{
System.debug('I am inside other city');
}
}
}

The same above code can be written as below:-

public class SwitchClass {

public static void cities(String cityName) {

switch on cityName {

when 'Pune' {
System.debug('I am inside pune');
}

when 'Nasik' {
System.debug('I am inside Nasik');
}

when 'Mumbai' {
System.debug('I am inside Mumbai');
}
when else {
System.debug('I am inside other city');
}
}
}
}

4. Enum Apex Class

● An enum is an abstract data type with values that each take on exactly one of
a finite set of identifiers that you specify. Enums are typically used to define a
set of possible values that don’t otherwise have a numerical order, such as
the suit of a card, or a particular season of the year.
● The easy way to think of them are compile-time “constants” that can be
statically typed. They’re sort of like a list of static strings, in that sense, and
they obey some interesting rules in addition to the basics:
● All enums have access to two methods: name() and ordinal() - name simply
returns the string version of your enum instance (the equivalent of toString for
enums), ordinal returns its index in the “list” — FirstValue would have an index
of 0 in the above example; SecondValue would have an index of 1.

5. Enum Example:-

public class EnumClass {

public enum Cities {PUNE, MUMBAI, HYDERABAD, BANGLORE, DELHI}

public static void enumMethods() {

Cities city = Cities.PUNE;


System.debug('Ordinal : '+city.ordinal()); //Returns Integer.
System.debug('Name : '+city.name()); //Returns String.
System.debug('Values : '+Cities.values()); //Returns List<String>
}
}
6. Using Switch when with Trigger.operationType:-

trigger AccountTrigger on Account (before update, before insert, before delete, after
update, after insert, after delete, after undelete) {

switch on Trigger.operationType {

when BEFORE_UPDATE {

//Write before update logic here


}

when BEFORE_INSERT {

//Write before insert logic here


}

when BEFORE_DELETE {

//Write before delete logic here


}

when AFTER_UPDATE {
//Write after update logic here
}

when AFTER_INSERT{

//Write after insert logic here


}

when AFTER_DELETE{

//Write after delete logic here


}

when AFTER_UNDELETE {

//Write after undelete logic here


}
}
}

7. Points to Remember

● You cannot perform DML on Trigger.new or Trigger.old


● Trigger.old and after triggers are read only.
● Trigger.new is editable but only in before triggers.
● You cannot use SOSL in trigger.
● Before triggers are used to update the same record or for validation purposes.
● Always bulkify your trigger.
● Do not use SOQL or DML inside for loops.
● Add null check wherever necessary.
29th June 2023

1. Write a trigger such that when Account Rating is Cold then


type must be prospect.

AccountTrigger.apxt

trigger AccountTrigger on Account (before insert) {

if(Trigger.isBefore) {
if(Trigger.isInsert) {
AccountTriggerHandler.typeProspect(Trigger.new);
}
}

AccountTriggerHandler.apxc

public class AccountTriggerHandler {

public static void typeProspect(List<Account> accNewList) {

for(Account acc : accNewList) {

if(acc.Rating == 'Cold') {
acc.Type = 'Prospect';
}
}
}
}

2. Write a trigger such that Rating is required field.

AccountTrigger.apxt

trigger AccountTrigger on Account (before update, before insert) {

if(Trigger.isBefore) {
if(Trigger.isInsert || Trigger.isUpdate) {
AccountTriggerHandler.ratingValidation(Trigger.new);
}
}
}

AccountTriggerHandler.apxc

public class AccountTriggerHandler {

public static void ratingValidation(List<Account> accNewList) {

for(Account acc : accNewList) {

if(acc.Rating == null) {
acc.addError(Account.Rating, 'Rating cannot be empty');
}
}
}
}

3. Write a trigger such that when Account Email is changed then


isActive must be true.

AccountTrigger.apxt

trigger AccountTrigger on Account (before update) {

if(Trigger.isBefore) {
if(Trigger.isUpdate) {
AccountTriggerHandler.isActiveCheck(Trigger.new, Trigger.old);
}
}
}

AccountTriggerHandler.apxc

public class AccountTriggerHandler {

public static void isActiveCheck(List<Account> accNewList, List<Account>


accOldList) {

for(Account accNew : accNewList) {

for(Account accOld : accOldList) {

if(accNew.Id == accOld.Id) {
if(accNew.Email__c != accOld.Email__c) {
accNew.isActive__c = true;
}
}
}
}
}
}

Do not try this above way use the below way:-

AccountTriggerHandler.apxc

public class AccountTriggerHandler {

public static void isActiveCheck(List<Account> accNewList, Map<Id, Account>


accOldMap) {

for(Account accNew : accNewList) {

//Account accOldRecord = accOldMap.get(accNew.Id);

if(accNew.Email__c != accOldMap.get(accNew.Id).Email__c) {
accNew.isActive__c = true;
}
}
}
}
Assignment:-

1. Write update code for #1 trigger above.


2. Write a trigger such that if Account Rating is ‘Cold’ then
Account Number must be a required field.
30th June 2023

1. Write a trigger such that when student enters his mobile no,
then make sure that mobile no is of 10 digits.

StudentTrigger.apxt

trigger StudentTrigger on Student__c (before insert, before update) {

if(Trigger.isBefore) {
if(Trigger.isInsert || Trigger.isUpdate) {
StudentTriggerHandler.mobileValidation(Trigger.new);
}
}
}

StudentTriggerHandler.apxc

public class StudentTriggerHandler {

public static void mobileValidation(List<Student__c> stdNewList) {

for(Student__c std : stdNewList) {


String mobileNo = std.Mobile_No__c;

if(std.Mobile_No__c != null && mobileNo.length() != 10) {


std.addError('Mobile no should be of 10 digits');
}
}
}
}

2. Write a trigger such that if Opportunity is Closed Won then


the record should be prevented from getting deleted.

OpportunityTrigger.apxt

trigger OpportunityTrigger on Opportunity (before delete) {

if(Trigger.isBefore) {
if(Trigger.isDelete) {
OpportunityTriggerHandler.preventDeletion(Trigger.old);
}
}
}

OpportunityTriggerHandler.apxc

public class OpportunityTriggerHandler {

public static void preventDeletion(List<Opportunity> oppOldList) {

for(Opportunity opp : oppOldList) {


if(opp.StageName == 'Closed Won') {
opp.addError('Closed Won Opp cannot be deleted');
}
}
}
}

3. Write a trigger such that if account has atleast one contact


then account must be non editable.

AccountTrigger.apxt

trigger AccountTrigger on Account (before update) {

if(Trigger.isBefore) {
if(Trigger.isUpdate) {
AccountTriggerHandler.preventUpdate(Trigger.new);
}
}
}

AccountTriggerHandler.apxc

public class AccountTriggerHandler {

public static void preventUpdate(List<Account> accNewList) {

Map<Id, Account> parentChildMap = new Map<Id, Account>([SELECT Id,


(SELECT Id FROM Contacts LIMIT 1) FROM Account WHERE Id = :accNewList]);

for(Account acc : accNewList) {


//Account mapAccount = parentChildMap.get(acc.Id);
if(!parentChildMap.get(acc.Id).Contacts.isEmpty()) {
acc.addError('You cannot edit this record.');
}
}
}
}

Assignment:-

1. Write a trigger such that if the Opportunity Stage Name is


Closed Won or Closed Lost then the Close Date must be
populated with today's date.

Note:- In this trigger when you write before update run the
trigger only when the stage name will be changed and it must
be Closed Won or Closed Lost. Write two separate methods
one method before insert and another method before update
and call these methods using the appropriate way from the
trigger.
2. Create a custom object Calculator. Create below fields on the
object:-

● Number 1
● Number 2
● Addition
● Subtraction
● Multiplication
● Division

All the above fields must have a number data type when
creating these fields. (Do not create formula fields here)
Write a trigger such that Number 1 and Number 2 will be
required fields. If Number 1 and Number 2 are not blank then
Addition, Subtraction, Multiplication and Division fields must
gets calculated based on Number 1 and Number 2.
If you have any questions regarding this please ping me once.

3. Write a trigger such that if an Account has any Child


Opportunity having StageName as ‘Closed Won’ then prevent
deletion of that Account.
4. Write a trigger such that when you create a new Lead with
Email as not null. Check if an existing lead is present with the
same email. If present throw an error message that “Duplicate
lead found with same email”.
5. Write a trigger on Account, when an account is inserted or
updated, automatically account billing address should
populate into the account shipping address.
6. Write a trigger such that age must be single or double digit.

You might also like