Salesforce Apex Trigger | Part 1

Salesforce Apex Trigger Basics

Previously we discussed how you can use DML operations, SOQL, SOSL in salesforce now it will help you to understand salesforce apex triggers.

So I am dividing this apex trigger into 3 levels i.e. Basic Level, Implementation Level and Advance Level so that It will help you to understand from very basics to advance.

So let's get started with all fundamentals.
Triggers :
Triggers are an Apex code that executes before or after the following types of DML operations :
 - Insert
 - Update
 - Delete
 - Merge
 - Upsert
 - Undelete

Triggers are divided into 2 types :
 1. Before Triggers
 2. After Triggers

1. Before Triggers :
Before triggers can be used to update or validate values of a record before they are saved to the database.
2. After Triggers :
After triggers can be used to access field values of the records that are stored in the database and use these values to make changes in other records.
Let's have a look at the syntax :
=============================================
trigger triggerName on objectName (trigger_events)
 {
     // your code here 
 }
=============================================

Where trigger_events can be a comma-separated list of events.

Types of events in the triggers :

1. Before Insert
2. Before Update
3. Before Delete
4. After Insert
5. After Update
6. After Delete
7. After Undelete

For Example : 
=============================================
trigger myExample on Account (before insert, after delete)

{

    // Your Code Here
}
=============================================

NOTE : 
  • Triggers can only contain keywords applicable to an inner class.
  • You do not have to commit the data manually, it automatically saves into the database.

Trigger.New :

Trigger.New is a context variable which contains a list of records which has caused the triggers to fire.
As this context variable, we are using in our example I have explained here. There are a few more which we will discuss in the next episodes.
Trigger.New can be used in the following trigger events :
 1. Before Insert
 2. Before Update
 3. After Insert
 4. After Update
 5. After Undelete
NOTE : There is no concept called Trigger.New in delete operations.

Now let's understand how it works 

First, create a table Customer
| CID | Name | Age | Phone |
----------------------------------
| 111 |  aaa   |  23   | 1234  |
| 222 |  bbb   |  34   | 3455  |
| 333 |  ccc    |  45   | 9876  |
----------------------------------

Now we will see how to use Trigger.New in before insert :
We have an object with three records :

| CID | Name | Age | Phone |
----------------------------------
| 111 |  aaa   |  23   | 1234  |
| 222 |  bbb   |  34   | 3455  |
| 333 |  ccc    |  45   | 9876  |
----------------------------------

In this object, if we are trying to insert new records into customer object
----------------------------------
| 444 |  ddd   |  43   | 1234  |
| 555 |  eee    |  23   | 3456  |
----------------------------------
Then the new records which we are trying to insert are stored in Trigger.new in before insert event.


Which means
List<Customer__c> cmr = Trigger.New
----------------------------------
| 444 |  ddd   |  43   | 1234  |
| 555 |  eee   |  23   | 3456  |
----------------------------------


These records are stored into Trigger.New

NOTE : The records which are stored in the Trigger.New we can directly perform changes in before insert.

For Example :
=============================================
for(customer__c : Trigger.New)

{

    c.Age__c = 23;

}
=============================================

Before insert event will occur before new records are inserted into the database. So we can not retrieve the new records using DML operations in before trigger i.e. when we have a customer table with following records.

| CID | Name | Age | Phone |
----------------------------------
| 111 |  aaa   |  23   | 1234  |
| 222 |  bbb   |  34   | 3455  |
| 333 |  ccc    |  45   | 9876  |
----------------------------------

When we are trying to perform insert these two new records 
----------------------------------
| 444 |  ddd   |  43   | 1234  |
| 555 |  eee   |  23   | 3456  |
----------------------------------

If there is any before insert triggers and we can have written any DML in it like below.
=============================================
trigger myExample on customer__c (before insert)
{
    List<customer__c> cmr = [SELECT cid__c, Name, Age__c, Phone__c FROM customer__c] 
    //This query will only fetch three records as remaining two records are not yet inserted
}
=============================================

Before Insert :
These triggers will fire when we are trying to insert a new record into a specified object.
Operations which we have written in the trigger will be implemented before new records are saved to the database.
In before Insert, Trigger.New stores the list of new records which we are trying to insert.

Let's have a look at scenario based triggers
Scenario 1 :
When we are trying to insert new record into object. If there is any record existing with same account name it should prevent duplicate record.
=============================================
trigger accountInsert on Account (before insert)

{

    for(Account acc : Trgger.New)

    {

     List<Account> mynew = [SELECT Id, Name FROM Account WHERE                                                       Name =: acc.Name];

     if(mynew.size() > 0)

     {

      acc.Name.addError('Account with same name is existing');

     } 

    }

}

=============================================

Scenario 2 :
Write a trigger to prefix Account Name with 'Mr.' when a new record is inserted.
=============================================

trigger accountprefix on Account(before insert)
{
    for(Account a : Trigger.New)
    {
        a.Name = 'Mr'+a.Name;
    }
}
=============================================

Scenario 3 :
Whenever a new record is created into an account object. Before this new record is inserted into Account, delete all the contacts records with this account name.
=============================================
trigger contactDeletion on Account(before insert)
{
    List<string> mynames = new List<string>();
    for(Account a : Trigger.New)
    {
        mynames.add(a.Name);
    }
    List<contact> mycontacts = [SELECT Id, Name FROM Contact                                                                   WHERE Name In: mynames];
    delete mycontacts;
}

=============================================

I hope these scenarios are clear to you.

AFTER INSERT :

This triggers will be fired after new records are successfully saved to the database.
We can use Trigger.New to refer to the list of new records which are have inserted.
On Trigger.New we can only perform read-only operations.
On the new list of records, we can perform DML operations.
On the new list of records, we can perform DML operations.
NOTE : On any records that are successfully saved to the database.
If we want to perform any changes on those records we have performed DML operations.

Example :


| CID | Name | Age | Phone |
----------------------------------
| 111 |  aaa   |  23   | 1234  |
| 222 |  bbb   |  34   | 3455  |
| 333 |  ccc    |  45   | 9876  |
----------------------------------

When we insert new records
----------------------------------
| 444 |  ddd   |  43   | 1234  |
| 555 |  eee   |  23   | 3456  |
----------------------------------

After triggers will be performed after committing the new records into a database which means.
| CID | Name | Age | Phone |
----------------------------------
| 111 |  aaa   |  23   | 1234  |
| 222 |  bbb   |  34   | 3455  |
| 333 |  ccc    |  45   | 9876  |
| 444 |  ddd   |  43   | 1234  |
| 555 |  eee   |  23   | 3456  |
----------------------------------

After sorting these records then after insert trigger will be called, So operation written in the trigger will be performed after records are successfully inserted.
Scenario  :
Whenever a new Contact is created for an account update the corresponding account phone with the new Contact phone field.
=============================================
trigger updatephone on contact(after insert)
{
    List<Account> acc = new List<Account>();
    for(Contact c : Trigger.New)
    {
      Account a = [SELECT Id, Phone, FROM Account WHERE Id =:                                           c.AccountId];
      a.phone = c.phone;
      acc.add(a);
    }
    update acc;
}
=============================================

These are some example scenarios where we can use these triggers.
This is how we can use before, after triggers In this EPISODE.
In the next episodes, we will discuss about DML operations, context variables, Recursive triggers, calling apex class in triggers etc. with a scenario so stay tuned...

WOHOOO !! YOU HAVE JUST COMPLETED SALESFORCE APEX TRIGGER PART 1 EPISODE
If you like this salesforcekid learning platform please let me know in the Comment section...Also, Share with your salesforce folks wish you 
Happy learning ☁️⚡️ (Learn. Help. Share.)

<< PREVIOUS                                                            NEXT >>
Salesforce Apex Trigger | Part 1 Salesforce Apex Trigger | Part 1 Reviewed by on Rating: 5

9 comments:

  1. Hi , SOQL inside forloop is a good practice?

    trigger updatephone on contact(after insert)
    {
    List acc = new List();
    for(Contact c : Trigger.New)
    {
    Account a = [SELECT Id, Phone, FROM Account WHERE Id =: c.AccountId];
    a.phone = c.phone;
    acc.add(a);
    }
    update acc;
    }

    ReplyDelete
    Replies
    1. No, SOQL inside for loop is not best practice.

      Delete
    2. Any reason for doing soql Account a = [SELECT Id, Phone, FROM Account WHERE Id =: c.AccountId]; inside the loop in your example?

      Delete
    3. As this episode is to understand the syntex and how to write it I have not mentioned about following best practices. In the upcoming Episodes I am going to mention examples with best practices as well.
      Thanks ��

      Delete
    4. Trigger UpdatePhone on Contact(before insert)
      {
      setaccId=new set();
      for(contact con:trigger.new)
      {
      accId.add(con.AccountId);
      }
      MapaccMap=new Map([select id,phone from Account where id IN:accId]);

      for(contact con:trigger.new)
      {
      if(accMap.containsKey(con.accountId))
      {

      con.mobilePhone=accMap.get(con.AccountId).phone;

      }
      }
      }

      Delete
  2. Anonymous7/15/2019

    Thats great learning, very good platform to learn basics

    ReplyDelete
  3. Can you please tell ne why below code not triggering when i am inserting duplicate account name.


    public class Basic {

    public static void mymethod(){
    List ACC = NEW List ();
    for(Account B : ACC){
    List rep = [Select id,Name from Account where Name =:B.Name];
    if(rep.size()>0)
    {
    B.Name.addError('Name is already exisit');

    }
    }
    }
    }



    -------------------------------------

    trigger Verify on Account (before insert) {
    if(trigger.isinsert && trigger.isbefore){

    Basic.mymethod();
    }

    }

    ReplyDelete
    Replies
    1. correct one is :)


      public class Basic {

      public static void mymethod(lIST ACC){
      for(Account B : ACC){
      List rep = [Select id,Name from Account where Name =:B.Name];
      if(rep.size()>0)
      {
      B.Name.addError('Name is already exisit');

      }
      }
      }
      }


      ---------------------------

      public class Basic {

      public static void mymethod(lIST ACC){
      for(Account B : ACC){
      List rep = [Select id,Name from Account where Name =:B.Name];
      if(rep.size()>0)
      {
      B.Name.addError('Name is already exisit');

      }
      }
      }
      }

      Delete
  4. How to write this apex?

    ReplyDelete

HELP !! SHARE !! SUGGEST !!

Powered by Blogger.