+ Start a Discussion
andyKal10andyKal10 

Yet another post on 'Initial Term of Field Expression must be concrete Sobject'

I have made a trigger that intercepts leads that are created by our web-to-lead form. The trigger ensures that there are no duplicate leads based on email, (which is probably an unnecessary safety step because I don't there is a way for two leads to be submitted by one web-form). It then packages those unique leads into a map and sends it over to the class I have pasted below. The goal of the class is to find existing leads and contacts and update them with the data supplied by the incoming lead, and then delete the incoming lead.

 

For each of the lines in Bold I get the 'Initial Term of Field Expression must be concrete Sobject' error. I think this is because the platform is assuming that 

newLeads.get(leadB.email)...

could return more than one result. So I am thinking that I have to prove that 'newLeads.get(leadB.email)' will only return one result, but I am not sure how to do this.

 

public with sharing class leadHandler {

Public Static Void leadDeDuper(Map<String,String> newLeads) {
Set<String> leadsToDelete = new Set<String>();
List<Lead> leadsToDeleteList = new List<Lead>();
List<Lead> existingLeads = new List<Lead>();
List<Contact> contactsToDelete = new List<Contact>();
List<Contact> existingContacts = new List<Contact>();

//finds existing Leads where their email equals the incoming Lead
for(Lead leadB : [select Id, Name, Blog__c,Email,HasOptedOutofEmail,Product_Announcements__c, MarketingCampaign__c, Insights_Newsletter__c,Press_Releases__c from Lead where Email IN :newLeads.KeySet()]) {
//adds the incoming lead to a set that will be deleted further down
leadsToDelete.add(newLeads.get(leadB.email));

//updates fields in existing leads
leadB.HasOptedOutOfEmail = false;
leadB.Press_Releases__c = newLeads.get(leadB.email).Press_Releases__c;
leadB.Insights_Newsletter__c = newLeads.get(leadB.email).Insights_Newsletter__c;
leadB.Product_Announcements__c = newLeads.get(leadB.email).Product_Announcements__c;
leadB.Blog__c =newLeads.get(leadB.email).Blog__c;
leadB.Marketing_Opt_Out__c = false;

existingLeads.add(leadB);
}

if(existingLeads.size()>0) {
update existingLeads;
}
//finds existing contacts where their email equals the incoming leads
for(Contact contactA : [select ID, Name, Email, HasOptedOutofEmail, Insights_Newsletter__c, Press_Releases__c from Contact where Email IN :newLeads.keySet()]) {

//adds the lead to a set to be deleted below
leadsToDelete.add(newLeads.get(contactA.Email));

//updates the existing contact
contactA.HasOptedOutOfEmail = false;
contactA.Insights_Newsletter__c = newLeads.get(contactA.email).Insights_Newsletter__c;
contactA.Press_Releases__c = newLeads.get(contactA.email).Press_Releases__c;
contactA.Product_Announcements__c = newLeads.get(contactA.email).Product_Announcements__c;
contactA.Blog__c = newLeads.get(contactA.email).Blog__c;


existingContacts.add(contactA);
}

if(existingContacts.size()>0) {
update existingContacts;
}

if(leadsToDelete.size()>0) {
for(Lead dLead : [Select ID from Lead where ID IN:leadsToDelete]) {
leadsToDeleteList.add(dLead);
}
delete leadsToDeleteList;
}

}

}

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Jeremy_nJeremy_n

"newLeads.get(leadB.email)" evaluates to a String, not an object. You will need to query using that String as an ID to get the actual Lead object you're trying to reference. I would probably send those to a map of id to object on the new leads:

 

 

map<id, Lead> newleadmap = new map<id, Lead> ([select Id, Name,
 Blog__c,Email,HasOptedOutofEmail,Product_Announcements__c, MarketingCampaign__c,
Insights_Newsletter__c,Press_Releases__c from Lead where id in :newLeads.values()]);

 Then where you currently have "newLeads.get(leadB.email)", substitute "newleadmap.get(newLeads.get(leadB.email))". This evaluates to an object, and can be updated.

 

Good luck!

 

Jeremy

 

All Answers

Jeremy_nJeremy_n

"newLeads.get(leadB.email)" evaluates to a String, not an object. You will need to query using that String as an ID to get the actual Lead object you're trying to reference. I would probably send those to a map of id to object on the new leads:

 

 

map<id, Lead> newleadmap = new map<id, Lead> ([select Id, Name,
 Blog__c,Email,HasOptedOutofEmail,Product_Announcements__c, MarketingCampaign__c,
Insights_Newsletter__c,Press_Releases__c from Lead where id in :newLeads.values()]);

 Then where you currently have "newLeads.get(leadB.email)", substitute "newleadmap.get(newLeads.get(leadB.email))". This evaluates to an object, and can be updated.

 

Good luck!

 

Jeremy

 

This was selected as the best answer
andyKal10andyKal10

Awesome. Thank you!