I am having a beastly time trying to in a trigger, check the oldmap vs new map, if a certain value exists, check for existence of a row in another object, if that row exists update, otherwise insert a new row.

the trigger is calling this function after update

I have the update working fine, its the insert of a new row when none exist that is jamming me up, the insert of new records is not working, the update of existing records is. I have tried replacing the upsert with an insert of new records/update of existing records, and a variety of other combinations, no dice

i abbreviated some of the trigger if additional code is needed let me know

 Map<Id, Contact> changedMap = new Map<Id, Contact>();

      for(Contact con : newMap.values()) {
          if(con.Magazine__c != oldMap.get(con.Id).Magazine__c){ 
              changedMap.put(con.id, con);

      if (changedMap.size() > 0){
        List<Contact_Preferences__c> preferences = new List<Contact_Preferences__c>();

        for(Contact_Preferences__c prefs : [SELECT Id, Constituent__c FROM Contact_Preferences__c 
          where Category__c = :magId]){

          Contact cnt = changedMap.get(prefs.Constituent__c);
          if(cnt != null){ //this works fine
                  prefs.Okay_to_Engage__c = true;
                  prefs.Okay_to_Solicit__c = true;
                  prefs.Okay_to_Engage__c = false;
                  prefs.Okay_to_Solicit__c = false;
          } else { //this does not fire

              Contact_Preferences__c cp = new Contact_Preferences__c(Category__c= magId, Constituent__c = cnt.Id, Comment__c = '', Okay_to_Engage__c = false, Okay_to_Solicit__c = false);

        if(preferences.size() > 0)
  • 4
    Trigger.oldMap is not available in before insert or after insert trigger contexts, which I'd expect is causing at least part of your issues. As always "It's not working" is not a helpful statement. Please edit your question to replace that with a detailed description of what "not working" means in this particular instance. If you're getting an error message, include the entire text of the error message verbatim (without paraphrasing) – Derek F Nov 8 '18 at 18:05
  • @DerekF sorry, i updated the question with both items you mentioned which would have been super helpful. the trigger fires after update, and its not working has been repalced with, updating current records works fine, the insertion of new records if one doesnt exist does not – Jay Rizzi Nov 8 '18 at 18:21
  • Ah, the "upsert" in your title was throwing me off (I thought your trigger was being fired from an upsert instead of you upserting Contact_Preferences__c records). Taking another look, I don't think the else block you've marked makes a lot of sense. I read this code as If we have a preference, but the related contact isn't taking part in this trigger, create a new preference with the non-existent contact's Id. I think you may want to re-evaluate that. Perhaps you mean to instead be checking if one of your contacts doesn't have a preference record? – Derek F Nov 8 '18 at 18:32

Basically, the else logic doesn't work, because you're only checking for existing preferences; you actually want to check if the contact has existing preferences, which is a different problem statement entirely. Here's an optimized version that should get you started.

Map<Id, Contact_Preferences__c> prefs = new Map<Id, Contact_Preferences__c>();
for(Contact con : newMap.values()) {
    if(con.Magazine__c != oldMap.get(con.Id).Magazine__c){ 
            // Assume they don't have a preference record already
            new Contact_Preferences__c(
                Category__c= magId, 
                Constituent__c = con.Id, 
                Okay_to_Engage__c = con.Magazine__c,
                Okay_to_Solicit__c = con.Magazine__c)
if(!prefs.isEmpty()) {
    for(Contact_Preferences__c pref : [SELECT Id, Constituent__c FROM Contact_Preferences__c 
        where Category__c = :magId and Constituent__c = :prefs.keySet()]){
            // Match consitutient, update pref to new value
            Contact con = prefs.get(pref.Constituent__c);
            // Set values; daisy-chain assignment is allowed for compatible types
            pref.Okay_to_Engage__c = pref.Okay_to_Solicit__c = con.Magazine__c;
            // Replace default with already existing record
            prefs.put(con.Id, pref);
// No need to check if empty first, empty list is no-op.
upsert prefs.values();
| improve this answer | |
  • thanks, learned alot, got me started, edited a couple of small items on your answer that were syntax stuff but it worked beautifully, thanks – Jay Rizzi Nov 8 '18 at 19:46
  • @JayRizzi I've been writing Lightning code all day, so it kind of slipped through. – sfdcfox Nov 8 '18 at 19:59

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.