2

I have implement a before update trigger. I want to fetch the old value which was there and new value which i just entered to update.

I have used trigger.newMap.keyset() and trigger.oldMap.keyset(), but I am getting same data in both i.e old value.

Here is my code:

if (Trigger.isUpdate && Trigger.isBefore) {
    List<CountParent__c> incCount;
    Set<id> triggerIds = Trigger.oldMap.keySet();
    List<CountChild__c> fetchChild = [select Name, CountParent__r.name from CountChild__c where Id IN: triggerIds];
    system.debug('old====' + fetchChild);
    Set<id> triggerIds1 = Trigger.newMap.keySet();
    List<CountChild__c> fetchChild1 = [select Name, CountParent__r.name from CountChild__c where Id IN: triggerIds1];
    system.debug('new====' + fetchChild1);
    List<CountParent__c> fetchParent = [select Name, NoOfChildRecords__c from CountParent__c];
    for (CountChild__c a: fetchChild1) {
        for (CountParent__c b: fetchParent) {
            if (b.Name == a.CountParent__r.Name) {
                incCount = new List < CountParent__c > ();
                b.NoOfChildRecords__c = b.NoOfChildRecords__c + 1;
                incCount.add(b);
            }
        }
    }
    update incCount;
}
-1

Hai cooolranjan try this new code snippet.

trigger updateCount on CountChild__c(After Insert, After Update) {

    if(trigger.isAfter && (trigger.isInsert || trigger.isUpdate)) {

        Set<Id> parentIds = new Set<Id>();    // intialize set of Id stores parentId
        List<CountParent__c> parentListForUpdate = new List<CountParent__c>();  // Initialize Parent Record List
        Map<Id,Integer> parentIdAndChildCountMap = new Map<Id,Integer>();   // initialize parentId and child count Map

        for(CountChild__c child : trigger.new) {  // Trigger.new records
            if(child.CountParent__c != null) { 

                if(trigger.isInsert) {    // If trigger is insert directly add parent Id in a set
                    parentIds.add(child.CountParent__c);    
                }

                // If trigger is update check parent Id change or not then add parent Id in a set
                if(trigger.isUpdate && trigger.oldMap.get(child.Id).CountParent__c != child.CountParent__c) {    

                    parentIds.add(child.CountParent__c);    // new parent Id

                    if(trigger.oldMap.get(child.Id).CountParent__c != null) {
                        parentIds.add(trigger.oldMap.get(child.Id).CountParent__c);    // old parent Id
                    }
                }
            }
        }

        if(parentIds.size() > 0) {    
            //Query the new and old parent child records and added the count into the map
            for(CountChild__c child : [SELECT Id,Name,CountParent__c FROM CountChild__c WHERE CountParent__c IN :parentIds]) {

                if(!parentIdAndChildCountMap.containsKey(child.CountParent__c)) 
                    parentIdAndChildCountMap.put(child.CountParent__c, 0);    // Initialize the count set to '0'

                parentIdAndChildCountMap.put(child.CountParent__c, parentIdAndChildCountMap.get(child.CountParent__c)+1);
            }
        }

        if(parentIdAndChildCountMap.size() > 0) {
            for(Id parentId : parentIds) {    // parentid  looping

                CountParent__c parent = new CountParent__c();    //intialize new parent Instance
                parent.Id = parentId;
                if(parentIdAndChildCountMap.containsKey(parentId)) {
                    parent.NoOfChildRecords__c = parentIdAndChildCountMap.get(parentId);    //get count put to the NoOfChildRecords__c field value
                } else {
                    parent.NoOfChildRecords__c = 0;    // if the parentId doesn't contais map to put 0
                }
                parentListForUpdate.add(parent);    //Added parent list
            }
        }

        if(parentListForUpdate.size() > 0) {
            update parentListForUpdate;    // Update the parent List
        }
    }
}
  • almost working as desired. thank you so much @MSCB – Ranjank Jul 8 '16 at 11:24
  • your welcome @Cooolranjan – MSCB Jul 8 '16 at 11:35
  • hi@MSCB , counter is stuck at 1. it needs to zero if no record is associated to that particular parent. – Ranjank Jul 8 '16 at 12:29
  • Check my updated code and verify. @Cooolranjan – MSCB Jul 8 '16 at 13:06
  • Still it's showing 1 since it should shown 0. – Ranjank Jul 8 '16 at 13:13
15

Old or New, the Ids are same for the records. You can compare field values between the old and new values.

  • Trigger.newMap - A map of IDs to the new versions of the sObject records.
  • Trigger.oldMap - A map of IDs to the old versions of the sObject records.
  • Trigger.new - Returns a list of the new versions of the sObject records.
  • Trigger.old - Returns a list of the old versions of the sObject records.

You have to deal with these maps to get the required version and compare the fields. Also note that relationship fields will not be available in trigger context variables. (such as lookup fields as in your code CountParent__r.name).

Below is an sample of how to use these Trigger context variables. Get an idea from there and apply in your logic.

for(CountChild__c child : Trigger.new){  // iterates through new versions of records
    CountChild__c oldRecord = Trigger.oldMap.get(child.Id); // get the old version of the current record

    if(oldRecord.Name == child.Name){ // check whether the name is edited or not
        // do something
    }   
}

Read more about Trigger Context Variables

  • It might be worth mentioning that while workflow field updates will cause update triggers to run again, the field values in trigger.old and trigger.oldMap are not updated. If you're doing something like incrementing a value inside of a block that checks if the value is different in trigger.old and trigger.new, it's very easy to write a bug into your code that ends up incrementing your target value twice. Some trigger frameworks may handle this for you, but the best solution is to make all operations in such blocks idempotent (i.e. doing it more than once gives the same result) – Derek F Jul 5 '16 at 14:16
1

As said by others Trigger.newMap contains New version of records and Trigger.oldMap contains the old version of the same records .

But trigger.newMap.keyset() you have ID's of the records which will be same . So you have to compare trigger.newMap.get(Id) with trigger.oldMap.get(Id) .

-1
if(Trigger.isUpdate && Trigger.isBefore) {   // Check Before Update

    List<parentIdAndChildMap> parentListForUpdate = new List<parentIdAndChildMap>();  // Initialize Parent Record List
    Map<Id,List<CountChild__c>> parentIdAndChildMap = new Map<Id,List<CountChild__c>>();   //Initialize ParentId And List of Child Record Map

    for(CountChild__c child : trigger.new) {  // Trigger.new records
        if(child.CountParent__c != null) {   // Check Parent Id not equals to null in child records
            if(!parentIdAndChildMap.containsKey(child.CountParent__c)) // Check Parent Id availabe or not in the Map
                parentIdAndChildMap.put(child.CountParent__c, new List<CountChild__c> ());  // Initialize the List of Child Object
            parentIdAndChildMap.get(child.CountParent__c).add(child);  // Put child records in the Map
        }
    }

    if(parentIdAndChildMap.size() > 0) {
        for(CountParent__c parent : [select Name,NoOfChildRecords__c from CountParent__c where Id =:parentIdAndChildMap.keySet()]) {  // Query the parent records
            parent.NoOfChildRecords__c = parentIdAndChildMap.get(parent.Id).size();   // Replace the parent record count field value
            parentListForUpdate.add(parent); // Add parent List
        }
    }

    if(parentListForUpdate.size() > 0) {
        update parentListForUpdate;  // Update the parent records
    }
}

This code may help your scenario.

  • if(!parentIdAndChildMap.containsKey(child.CountParent__c)) sorry but this line seems ambiguous. for loop will exceute the record one by one. same parent record can be available in multiple child records. so, it will only include one id in map – Ranjank Jul 7 '16 at 11:07
  • Yes the parent Id available in the map to put the child record into the map value list. otherwise to put parent Id and initialize the new list of child – MSCB Jul 7 '16 at 11:18
  • Did you understand my answer? @Cooolranjan – MSCB Jul 8 '16 at 6:27
  • sorry but i did't get it . it's not working too. these lines might need to be modified i think. if(!parentIdAndChildMap.containsKey(child.CountParent__c)) parentIdAndChildMap.put(child.CountParent__c, new List<CountChild__c> ()); parentIdAndChildMap.get(child.CountParent__c).add(child); – Ranjank Jul 8 '16 at 7:59
  • Thanks for you reply. Actually what you want to update in parent records? – MSCB Jul 8 '16 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.