function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jessica PuckettJessica Puckett 

Invalid bind expression type of Contact for column of type String

Hello all,
I'm working on an Apex trigger and am running into an issue I'm not sure how to resolve.  (I'm still quite new to Apex.)  I'm receiving the following problem on lines 2 and 3:  "Invalid bind expression type of Contact for column of type String"  Suggestions are greatly appreciated! 
My trigger code is below:

trigger EmailDuplicate on Contact (before insert, before update, before delete) {
    List<Contact> emaillist = [SELECT id,email FROM Contact WHERE Email!=null AND Email IN :trigger.new];
    List<Contact> existingcontact = [SELECT id, email,lastname FROM Contact WHERE email IN :emaillist AND id NOT IN :trigger.new];
    for(Contact current : emaillist){
        for(Contact existing : existingcontact){
            if(current.Email==existing.Email){
                current.duplicate_email__c=true;
            }
                else if (current.Email!=existing.Email){
                    current.duplicate_email__c=false;
                    
                    update emaillist;
                }
            }
        }
    }

 
Raj VakatiRaj Vakati
Hi Jessey ,

Try like this 


trigger EmailDuplicate on Contact (before insert, before update, before delete) {
    
    Set<String> emaillistSet = new Set<String>() ;
    for(Contact c: [Select id, Email from Contact where email !=null]){
        emaillistSet.add(c.email) ;
    }
    
    
    List<Contact> emaillist = [SELECT id,email FROM Contact WHERE Email!=NULL AND Email IN : emaillistSet];
    
    List<Contact> existingcontact = [SELECT id, email,lastname FROM Contact WHERE Email  IN :emaillistSet AND id NOT IN :trigger.newMap.keySet()];
    
    for(Contact current : emaillist){
        for(Contact existing : existingcontact){
            if(current.Email==existing.Email){
              //  current.duplicate_email__c=true;
            }
            else if (current.Email!=existing.Email){
               // current.duplicate_email__c=false;
                
                update emaillist;
            }
        }
    }
}
 
Charisse de BelenCharisse de Belen
Hi Jessica,

The problem is that you are checking if Email, which is a String, is in Trigger.new (line 2) and in emaillist (line 3). Both Trigger.new and emaillist are lists containing Contacts, not Strings. You will have to refactor your logic to work around this.

Here's a hint (pseudo-code) for a possible solution:
Loop through each Contact in Trigger.new to create a map of current Contacts with email as key.

If the size of the map is greater than 0,
    Create a set of existing Contacts' Emails.

    Loop through each current Contact by using the map.values() method,
        If the set of existing Contacts' Emails contains the Email of the current Contact,
            Set current.Duplicate_Email__c to true.
        Else,
            Set current.Duplicate_Email__c to false.
        Add the current Contact to a list of contacts to be updated.
    
    Update the list of contacts to be updated.

If you're not familiar with Maps and Sets, please refer to these articles:
  • https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_map.htm
  • https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_set.htm

Once you come up with a refactored version of your trigger, feel free to post it here, and I will be happy to let you know if you're on the right track.
Charisse de BelenCharisse de Belen
Whoops! I just realized I made a mistake. You do not want to update the list of contacts to be updated (line 13 of my pseudo-code) because you cannot perform DML operations on the objects that fired the trigger. In other words, just remove lines 11 and 13, and you should be good.

Also, if you're struggling to find a solution using the pseudo-code from my previous answer, you can try this instead:
Loop through each Contact in Trigger.new to create a List of current Contacts and a List of their Emails.

If the size of either of the lists (doesn't matter which one) is greater than 0,
    Create a set of existing Contacts' Emails.

    Loop through the list of current Contacts,
        If the set of existing Contacts' Emails contains the Email of the current Contact,
            Set current.Duplicate_Email__c to true.
        Else,
            Set current.Duplicate_Email__c to false.

The difference between this solution and the last solution is that this one uses two Lists in line 1 where the previous one used a Map. Both should work just fine. But the code in my previous answer may be a useful practice in learning more Apex!