Browsing "Older Posts"

Browsing Category "Apex"
  • How to get RecordTypeId Based On RecordType Name In Apex Salesforce

    salesforcepoint Saturday, 16 October 2021

    Get RecordTypeId Based On RecordType Name In Apex

    Get RecordTypeId Based On RecordType Name In Apex


    In many use cases, we need to check recordtype conditions in apex logic. Below is the same peace of code that gives recordtypeId of given sobject name and recordType label.

    
      String egRecordTypeID = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Record Type Label').getRecordTypeId();
      

    Here we need to provide Sobject name in place of  "Case" and recordType label in place of "Record Type Label"
  • How to Use Safe Navigation Operator (?.) in Salesforce Apex | Winter 21 Release Notes

    salesforcepoint Monday, 31 August 2020

    How to Use the Safe Navigation Operator in Apex

    How to use Safe Navigation Operator in Apex Salesforce

    Hello guys, as part of salesforce winter 21 release, salesforce introduced Safe Navigation Operator( (?.) to avoid null pointer exceptions in apex. This is very useful feature for developers. If we need to check something (whether it is a object, map, list..) should not be null then we will write (?.) at the end.  If the left side of the expression(?.) is null, then right side is not evaluated and result will be null.

    Till now we used != null condition to check object is not null like below.

    if (object!= null){
       string s= object.fieldName;
    }

    we can write above code by using safe navigation operator like below
    string s= object?.fieldName;
    



    Example: In this example we have a accountIdAccountMap, it contains account id as key, account record as value. We need to get name of the account.

    string accountName = accountIdAccountMap.get(accId).Name; 
    // this will return null pointer exception if accId not available in the map.
    

    if account not exist on map we will get null pointer exception because we accessing null object for fetching name.

    Traditional approach to avoid above null pointer exception:

    if(accountIdAccountMap.get(accId) != null) {
     accountName = accountIdAccountMap.get(accId).Name;
    }

    OR
    if(accountIdAccountMap.containsKey(accId)) {
     accountName = accountIdAccountMap.get(accId).Name;
    }

    By using Safe Navigation operator:

    string Account Name = accountIdAccountMap.get(accId)?.Name;
    

    if we need to check whether map is not null then we can write

    accountIdAccountMap?.get(accId)?.Name;

  • Salesforce Apex Map & Map methods with Examples

    salesforcepoint Wednesday, 8 July 2020
    Salesforce Apex Map, Map methods with Examples
    Map is one of the collection type in salesforce apex. In this post we are going to see what are the map methods with some basic examples. First of all Map is a key and value pair i.e each and every value is associates with key. Here key is unique, that means if we put one key,value pair into Map, we should not add same key one more time. If key is already exist in map and once again you are trying to add key with different value then old value override with new value.

    Salesforce Apex Map Syntax:

    Map<dataType, dataType> variabeName ;

    If we don't initialize map and 'trying to put new set of key, value' Or trying to use any map methods on that variable, you will end up with null pointer exception. So we need to initialize map whenever we create map variable.

    Map<dataType, dataType> variabeName = new Map<dataType, dataType>();

    eg: Map<String, String> countryWithCapitalMap =  new Map<String, String>();

    Important Apex Map Methods:

    put( ): By using this method we can new set of key, value pair into map.
    example: countryWithCapitalMap.put('India', 'Delhi'); //here India is key & Delhi is corresponding value for key 'India'.

    containsKey(key): By using this method we can check whether key exist or not in Map. It will return true if key is exist in apex map.
    example: countryWithCapitalMap.containsKey('India') //true

    get(Key): It returns value of corresponding key.
    example:  countryWithCapitalMap.get('India') //reurns 'Delhi'

    isEmpty(): It returns true if Map does not contain any key, value pair.
    example:  countryWithCapitalMap.isEmpty() //false

    size():  It returns number of key, value pairs available in Map.
    example: countryWithCapitalMap.size() // 1

    keySet(): It returns SET of key's available in the map.
    example: countryWithCapitalMap.keySet() //{India}

    values(): It returns LIST of values available in map.
    example: countryWithCapitalMap.values() //{Delhi}

    Task: Create a map to store country as Key and corresponding countries as values.

    Country (Key)
    'United States'
    'India'
    States (Value)
    'California',
    'Colorado',
     'Texas' 
    'Andhra Prdesh',
    'Telangana',
    'Karnataka'

    One country can have multiple states so that we should create Map value as List<string>

    Map<String, List<String>> countryWithStatesMap = new Map<String, List<String>>();

    countryWithStatesMap.put('United States', new List<String>{'California','Colorado','Texas'});
    countryWithStatesMap.put('India', new List<String>{'Andhra Prdesh','Telangana','Karnataka'});

    system.debug('Get countries from countryWithStatesMap ===>'+countryWithStatesMap.keyset());
    // o/p: {India, United States}
    system.debug('Get States of India ===>'+countryWithStatesMap.get('India'));
    // o/p: (Andhra Prdesh, Telangana, Karnataka)
    system.debug('Is Srilanka there in Map ===>'+countryWithStatesMap.containsKey('Srilanka')); 
    // o/p: false
  • How To Compare Old Values And New Values In Salesforce Triggers

    salesforcepoint Monday, 2 December 2019

    How To Compare Old Values And New Values In Salesforce Triggers (How to check whether record values are changed or not in Apex Trigger)


    We know that salesforce Before update and After Update triggers fired/invoked based on Update DML event occurs, irrespective of any field value updated on record. But update triggers should not get invoked every time when record is updated. These trigger's should fire when corresponding field values got changed on record.

    If we want to know whether respective field value changed or not, we need to use trigger.new and trigger.oldMap context variables. As we know that trigger.New contains list of records which will have updated field values and trigger.OldMap contains map of records which will have old values. Lets take basic example: If Phone field value on Account got changed, then update Description field like "Phone number got updated from old Phone Number to New Number. Here the logic should not trigger every time, only gets triggered when only phone field value got updated.



    Trigger Helper Class

     public class Account_Helper {  
      public static void checkPhoneValueUpdated(List<account> newList, Map<Id,Account> oldMap) {  
        for(Account accountRecord: newList){  
        if(accountRecord.phone != oldMap.get(accountRecord.Id).phone){  
          accountRecord.description = 'Phone number got updated from'+oldMap.get(accountRecord.Id).phone+' to '+accountRecord.phone;  
         }  
        }  
      }  
     }  
    
    Trigger:
     Trigger AccountTrigger on Account(Before update){  
       if(trigger.isBefore &amp;&amp; trigger.isUpdate){  
         Account_Helper.checkPhoneValueUpdated(trigger.new, trigger.oldMap);  
       }  
     }  
    

  • Salesforce Apex Collections:SET & Set Methods with Examples

    salesforcepoint Thursday, 13 April 2017

    Set is a unordered collection of simillar datatype elements. Set doesn't allow duplicate elemets. Set will not maintain insertion order. Salesforce has predefined Apex class called Set .This class contains methods required to support the operations on the set .

    Syntax :

    Set<DataType> setName =new Set<DataType>();
                or
    Set<DataType> setName=new Set<DataType>(List/Set) ;

    Examples :
    Set<Integer> ages=new Set<Integer>();
    Set<String> names=new Set<String>();

    Methods : 
    add(ele):  This method is used to add new elements into the set .
    Example :
    Set<Integer> ages=new Set<Integer>();
    ages.add(90);
    ages.add(30);
    ages.add(10);
    ages.add(90);
    System.debug(ages); //  {10,30,90 }

    addAll(set/list) : This method is used to add list /set of elements to a set .

    Example:
    List<Integer> values =new List<Integer>{10,90,30,40};
    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(80);
    ages.addAll(values); // All the elements in the values are added to ages.
    System.debug(ages);  // { 10,30,40,80,90}


    remove(ele) : This method is used to remove given element from the set.

    Example :
    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(20);
    ages.add(30);
    System.debug(ages); // {10,20,30 }
    ages.remove(20);
    System.debug(ages); // {10,30 }

    removeAll(list/set) : This method is used to remove list or set of elements from the set.

    List<Integer> values=new List<Integer>{10,90,40};
    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(30);
    ages.add(90);
    ages.add(50);
    System.debug(ages); // {10,30,50,90 }
    ages.removeAll(values); // All the elements which are in values ,remove them from the set ages.
    System.debug(ages); // { 30,50}

    clear(): This method will remove all the elements from the set .
    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(30);
    ages.add(90);
    System.debug(ages); // { 10,30,90}
    ages.clear();
    System.debug(ages); {}


    size()  : This will return  count of no of elements in the set .

    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(30);
    ages.add(90);
    ages.add(50);
    Integer count= ages.size();
    System.debug(count) ; // 4

    contains(ele) : This method will return true ,if the set contains the given element.

    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(30);
    ages.add(90);
    ages.add(50);
    System.debug(ages); // {10, 30,50,90}

    Boolean flag1 =ages.contains(10);
    System.debug(flag1); // true
    Boolean flag2 =ages.contains(80); // false
    System.debug(flag2); // false

    containsAll(set/list) : This method will return if all the elements in the set/list are available


    List<Integer> values=new List<Integer>{10,40,90};
    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(30);
    ages.add(90);
    ages.add(50);
    System.debug(ages); // {10,30,50,90 }
    Boolean flag1= ages.containsAll(values);
    System.debug(flag1);// false

    Set<Integer> myData=new Set<Integer>{10,30};
    Boolean flag2=ages.containsAll(myData);
    System.debug(flag2); // true

    retainAll(set/list): This will retain the common elements in the set  and given list/set.

    List<Integer> values=new List<Integer>{10,40,90};
    Set<Integer> ages=new Set<Integer>();
    ages.add(10);
    ages.add(30);
    ages.add(90);
    ages.add(50);
    System.debug(ages); // {10,30,50,90 }
    ages.retainAll(values);
    System.debug(ages); // {10,90}

    isEmpty() : This will return true if the set is empty .
    Set<Integer> ages=new Set<Integer>();
    System.debug(ages.isEmpty()); // true
    Set<Integer> values ;
    values.isEmpty(); // error  null pointer exception

    List & List Methods with Examples
  • Salesforce Apex Collections: List & List Methods with Examples

    salesforcepoint

    List is a collection of simillar Datatype elements .DataType can be any thing that is supported by apex (Primitive,Sobjects, collections, Wrapper classes..). The  size of the list can grow or reduce based on run time requirement .

    -Elements in the list maintains insertion order .
    - list allows Duplicate elements .
    -In the salesforce we have predefined apex class List .
    -There are some predefined methods to support list operations.

    Syntax for List Creation:

     List<DataType> listName =new List<DataType>();

    Example:

    List<Integer> ages=new List<Integer>();

    Salesforce Apex List Methods with Examples

    add(element) : This method is used to add new element into the list at the last position .

    Example :

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(20);

    System.debug(ages); // { 10,20,20}


    add(index,element) : This method is used to add new Element at the given index. Index value in the list starts with  zero

         0    1     2
    ------------------
    | 10 |  20 | 20  |
    ------------------

    ages.add(2,60);

      0    1     2    3
    -----------------------
    | 10 | 20  | 60 | 20  |
    -----------------------

    System.debug(ages); //  { 10,40,20,30 }

    addAll(List|Set) :  This method is used to add set|List of elements into the list.

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(30);

    System.debug(ages); //  { 10,20,30 }

    List<Integer> myList=new List<Integer>();

    myList.add(10);

    myList.add(90);

    myList.add(40);

    System.debug(myList); // { 10,90,40}

    myList.addAll(ages);  // All  the elemenets which are in ages are added to myList.

    System.debug(myList); // { 10,90,40,10,20,30 }


    get(index) : This method will return the element which is at the given index .

    Example :

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(30);

    ages.add(40);

    System.debug(ages);  // {10,20,30,40 }

     0    1     2   3
    ---------------------
    | 10 | 20 | 30 | 40 |
    ---------------------

    Integer a=ages.get(2);

    System.debug(a); // 30

    Integer b=ages.get(3);

    System.debug(b); // 40

    Integer c=ages.get(0);

    System.debug(c); // 10

    remove(index) : This method will remove the element at the given index .

    Example :  List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(30);

    ages.add(40);

    ages.add(90);

    System.debug(ages);  // { 10,30,40,90 }

     0      1      2     3
    ---------------------------
    | 10  |  30  |  40  | 90  |
    ---------------------------

    ages.remove(2);

    System.debug(ages); //  { 10, 30, 90}

     0      1     2
    -------------------
    | 10  |  30  | 90 |
    -------------------

    ages.remove(1);

    System.debug(ages); // { 10,90 }

      0      1
    --------------
    |  10   | 90  |
    --------------
    clear() : This method will remove all the elements in the list .

    Example :

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(30);

    System.debug(ages); // { 10, 20,30 }

    ages.clear();

    System.debug(ages); // {}

    sort() : This method is used to sort the elements in the ascending order .

    Example :

    List<Integer> ages = new List<Integer>();

    ages.add(10);

    ages.add(90);

    ages.add(30);

    ages.add(70);

    System.debug(ages); //  { 10,90,30,70 }

    ages.sort();

    System.debug(ages); //  { 10,30,70,90 }


    clone() : This will create a duplicate copy of list of elements

    Example :

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(30);

    List<Integer> values=ages.clone();

    System.debug(ages); // { 10,20,30 }

    System.debug(values); // { 10,20,30}

    values.add(90); // Changes made on values will not effect ages

    System.debug(values); // { 10,20,30,90}

    System.debug(ages); // {10,20,30} // Changes made on ages will not effect values.


    deepClone() : Makes a duplicate copy of a list of sObject records,
    including the sObject records themselves

    Example : List<Account> accs= new List<Account>();

    Account a1=new Account(Name='Wipro',Industry='Banking');

    accs.add(a1);

    Account a2=new Account(Name='TCS',Industry='Energy');

    accs.add(a2)

    System.debug(accs); // {  Account :{Name=Wipro ,Industry=Banking } ,

     Account :{Name =TCS ,Industry=Energy} }

    }

    List<Account> dupLicates=accs.deepClone();

    System.debug(dupLicates); // {  Account :{Name=Wipro ,Industry=Banking } ,

      Account :{Name =TCS ,Industry=Energy} }

         }


    Notes : Any changes made on accs elements will also be applied on duplicates


    size() : This will return no of elements in the list .

    Example :

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(30);

    Integer count =ages.size();

    System.debug(count); // 3


     set(Index,ele) : This will replace  the element at the given index with value .

    Example :

    List<Integer> ages=new List<Integer>();

    ages.add(10);

    ages.add(20);

    ages.add(30);

    ages.add(40);

    System.debug(ages); // {10,20,30,40 }

    ages.set(1,90);

    System.debug(ages); // { 10,90,30,40 }

    ages.set(3,55);

    System.debug(ages); // {10,90,30,55}
  • Difference Between Trigger.New and Trigger.old with Example

    salesforcepoint Monday, 20 February 2017
    Trigger.new and Trigger.old both are context variables in Salesforce. 

    Trigger.New: Trigger.new returns List of new records which are trying to insert/update into Database. This is available in Before Insert, Before Update, After Insert,  After Update Triggers and undelete Triggers. This list of records can only modified in Before triggers.

    Trigger.Old: Trigger.old returns List of old records which are updated with new values. These List of records already there in Database. Trigger.old available in Before update, after update, Before Delete and After Delete triggers.


    Before Insert Trigger
    -----------------------
    Trigger.new- What are the records going to insert into Database [not commited yet, id=null]
    trigger.old- NULL
    Trigger.newmap-null
    Trigger.old-Null


    Afeter Insert
    -----------------------------
    Trigger.new- New List of Records which are  inserted
    Trigger.old- null
    Trigger.NewMap- New Map<ID, new Record>
    Trigger.oldMap- Null


    Before Update
    ------------------------------
    Trigger.new- New List of Records which are going to be updated
    Trigger.old- List of  Records with old values.
    Trigger.NewMap- New Map<ID, new Record>
    Trigger.oldMap- Old Map<ID, old record>


    After Update
    -------------------------------
    Trigger.new- New List of Records which are  updated
    Trigger.old- List of  Records with old values.
    Trigger.NewMap- New Map<ID, new Record>
    Trigger.oldMap- Old Map<ID, old record>

    Example: I have a scenario like when Account Phone number is updated then Account Description value should be updated with old phone number+new phone number.

    trigger NewVsOld on Account (before update) {
        for(integer i=0; i<trigger.new.size();i++){
    /*if Old Phone number and New phone number are not same then Description field will be updated with Old phone number+New phone number. if same no change will be in Description field*/
        if(trigger.old[i].phone!=trigger.new[i].phone){
            trigger.new[i].description='old phone number is  ' + trigger.old[i].phone + ' and New Phone number is ' +trigger.new[i].phone ;
       }
     }
    } 



    Here i have created one new Account record with phone number 7799703404
    I have updated phone number 7799703404 with new phone number 8897125248 and saved the record. Then description field automatically updated with "old phone number is  (779) 970-3404 and New Phone number is (889) 712-5248".


    In above Example Trigger.new record holds new phone number 887125248 and Trigger.old holds old phone number 7799703404.
  • Trigger Execution Process in Salesforce| Order Of Trigger Execution

    salesforcepoint Thursday, 9 February 2017

    1) Loads the  record from the database or initializes the record for an upsert statement.
    2) Loads the new record field values from the request and overwrites the old values with new values.

    If the request came from a standard User Interface edit page,  runs system validation to check the record for:
      -Checks whether Required values is present or not at the page layout level and field-definition level
      -checks field formats are valid or not (example:  Email ID format, Phone number format)
    3) All before triggers execution.
    4) Runs most system validation steps again, such as verifying that all required fields have a non-null value, and then runs any custom validation rules. The only system validation that Salesforce doesn’t run a second time (when the request comes from a standard UI edit page) is the enforcement of layout-specific rules.
    5) Saves the record to the database, but doesn’t commit yet to Database.
    6) all after triggers Executed.

    7) Run assignment rules and auto-response rules.
    8) workflow rules Executed.
    9) If there is any workflow field update, updates the record again.
    10) If the record  updated with workflow field update, fires before and after triggers one more time (and only one more time), in addition to standard validations. Custom validation rules are not run again.
    11) escalation rules executed.
    12) If the record contains a roll-up summary field, rollup summary fields are calculated and updated.
    13) Run Criteria Based Sharing evaluation.
    14) Commits all DML operations to the database.
    15) Run post-commit logic, such as sending email.
  • Salesforce Apex Triggers Best Practices

    salesforcepoint
    Salesforce Apex Triggers Best Practices

    Important Salesforce Apex Triggers Best Practices

    1) Write One Trigger per one Object
    You can have n number of triggers on single object, but as apex best practice we should write  logic in handler class. If you write multiple Triggers on single object, we cant control order of execution .


    2) Always write Logic-less Triggers
    Always write logic in apex handler or helper class so that we can reuse it. Create context-specific handler methods in trigger handler class.

    3) Always Bulkify your Code
    your code must work on more than one record at a time.
    Bulkifying Apex code means  we make sure the code properly handles more than one record at a time. The trigger code must be process on multiple  records instead of single record for avoid hitting governor limits.


    4) Always Avoid SOQL Queries and DML statements inside FOR Loops
    This is one of the salesforce apex best practices. Since apex is running under Multi-tenant architecture it strictly enforces some governor limits to control wastage of resource utilization. if we use soql inside for loop, that may causes to hit governor Limits.


    If we write  SOQL query inside for loop that iterates across all object records. Soql query will be executed for each record. An individual Apex request works 100 SOQL queries before exceeding that governor limit. So if the trigger is invoked by a batch of more than 100 records, the governor limit will throw a runtime exception.

    Total number of SOQL queries issued for a single Apex transaction- 100
    Total number of DML statements issued-150


    5) Using Collections, Streamlining Queries, and Efficient For Loops to avoid governors.
    It is important to use Apex Collections(LIST, SET,MAP)  to efficiently query data and store the data in memory. As a good developer you should learn effective usage of Map.



    6)Avoid to Query Large Data Sets
    The total number of records that can be returned by SOQL queries in a request is 50,000. If returning a large set of queries causes you to exceed your heap limit, then Use SOQL  with proper filter conditions(Where conditions) , to avoid 50001 limit error.

    7) Use @future Appropriately
    @Future is used to run processes in a separate thread, at a later time when system resources become available. @Future have Future methods that will runs asynchronously.

    8) Avoid Hard-coding IDs
    Don't hard code IDs into queries or apex code. Rather query on some other data to retrieve the desired rows. Record Id's can change across org's.

    9) Handle recursion
    As triggers gets invoked automatically when dml occurs, there could be scenarios where same trigger logic gets called multiple times. This may cause unnecessary resource consumption (Query, cpu time, dml). So we need to handle such code of scenarios effectively.