0

Pretty new to development, so I'm probably missing something easy. From advice on this site, I'm trying to move my org's triggers into a trigger handler to be more manageable. I've started converting my triggers into classes, however when I try to call a method of one of these classes, I'm getting a Constructor not defined error.

Here is my constructor:

public class AddProductFromOfferingId { 

    Map<Id, Lead> newLeads;

    public AddProductFromOfferingId(Map<Id, Lead> newTriggerLeads)
    {
        newLeads = newTriggerLeads;
    }
}

And here's where I try to call the constructor:

public void beforeInsert(SObject so)
    {
        // Cast the SObject to an Lead
        Lead theLead = (Lead)so;

        if(theLead.Offering_ID__c != null)
        {
            AddProductFromOfferingId addProd = new AddProductFromOfferingId(Trigger.newMap);
        }

The full error is: Constructor not defined: [AddProductFromOfferingId].<Constructor>(Map<Id, SOBject>).

In the constructor, I've named it AddProductFromOfferingId, requiring one Id, Lead map to be passed in. In my TriggerHandler class (second code snippet), I'm passing in a map. Can I not use Trigger.newMap in this way?

Update:

Thanks @BrianMansfield, your comment gave me what I needed. Adding the following to the handler class fixed my issue:

Map<Id, Lead> newMapFromTrigger = (Map<Id, Lead>) Trigger.newMap;
2
  • Where is beforeInsert being called from? It's probably because you've defined the constructor to take in a Map<Id, Lead> and you're passing it a Map<Id, base sObject>...try explicitly casting Trigger.newMap to a Map<Id, Lead> Oct 4 '16 at 21:29
  • beforeInsert is being called in my LeadHandler class, which is where I plan to call all triggers-turned-classes. When I try to set Trigger.newMap to an <Id, Lead> map, I get an error saying the types don't match, so I believe you're right! Just need to figure out how to get Trigger.newMap to change into an <Id, Lead> map instead of an <Id, SObject> map.
    – krisuvik
    Oct 4 '16 at 21:36
3

A bit of a way around it but you can cast the Map<ID,sObject> to the Map<ID,Lead> as follows:

//This lines could simply be your trigger.newMap records, query is just an example
Map<ID,sObject> l = New Map<ID,sObject>([Select ID From Lead limit 1]);

//Actual conversion here
Map<ID,Lead> a = New Map<ID,Lead>((Lead[])l.values());

BUT, I would change (if it makes sense) the constructor to:

AddProductFromOfferingId(Map<ID,sObject> newTriggerLeads){
     //If null or no records, nothing to do
     if(newTriggerLeads == null || newTriggerLeads.isEmpty()) return;

     //If we have lead records cast to a list of leads and do what we need to
     if(newTriggerLeads[0].getsObjectType() == Lead.sObjectType()){
          Lead[] theLeads = (List<Leads>)newTriggerLeads.values();
     }else{ //Not leads, do nothing
        return;
     }

}

Or something like that

4
  • ?? why is Account showing up in your first code sample? typo?
    – cropredy
    Oct 4 '16 at 22:18
  • @cropredy - oops. I had sample as Account and was trying to change it to lead when posting. Did not get them all. Should be good now, thanks
    – Eric
    Oct 4 '16 at 22:19
  • Thanks @Eric! Would you still need to include the line if(newTriggerLeads[0].getObjectType() == Lead.sObjectType()) if this is only called on a Lead Handler class? For example, if I have a handler class for each SObject, and this method is only called for leads, that shouldn't be necessary right? Just trying to make sure I understand!
    – krisuvik
    Oct 5 '16 at 14:30
  • @krisuvik - correct
    – Eric
    Oct 5 '16 at 16:38

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.