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
BrittanieBrittanie 

APEX Trigger Update Task Field from Contact Field

Trying to write (my first) trigger to pull from a picklist field on the Contact to a duplicate picklist on a Task field.

Contact field info is 

Field Label: SOI

Object Name: Contact

Field Name: SOI

Data Type: Picklist

API Name: SOI__c

 

Task Field Info is

Field Label: Contact's SOI

Object Name: Activity

Field Name: Contacts_SOI

Data Type: Picklist

API Name: Contacts_SOI__c

 

I currently receive the error message:

Error: Compile Error: Incompatible key type Schema.SObjectField for MAP<Id,LIST<Task>> at line 6 column 20
 

 

The code that I am trying to use is:

 

Trigger TaskBefore on Task(before insert, before update){
Map<Id, List<Task>> whoIds = new Map<Id, List<Task>>{};
For (Task t : trigger.new)
If(t.WhoId != null){
List<Task> tasks = whoIds.get(task.WhoId);
If (tasks == null){
tasks = new List<Task>{};
whoIds.put(t.WhoId, tasks);
}
tasks.add(t);
}
For(Contact con : [Select Id, Name,SOI__c from Contact where Id in :whoIds.keySet()])
For(Task t : whoIds.get(con.id))

t.contacts_SOI__c = con.SOI__c;}

 

Please help!

 

 

Best Answer chosen by Admin (Salesforce Developers) 
BrittanieBrittanie

final working code

 

Trigger Task_SOI on Task(before insert, before update){
   
   
    Map<Id, List<Task>> whoIdsMap = new Map<Id, List<Task>>();
    
    for(Task t : trigger.new){
       
        if(t.WhoId != null){
            
            if(!whoIdsMap.containsKey(t.WhoId)){
                
                List<Task> temp = new List<Task>();
                
                temp.add(t);
               
                whoIdsMap.put(t.WhoId, temp);
            }else{
                
                whoIdsMap.get(t.WhoId).add(t);
            }
        }
    }
   
    
    for(Contact con : [Select Id, Name,SOI__c  from Contact where Id in :whoIdsMap.keySet()]){
        
        for(Task t :whoIdsMap.get(con.Id)){
            t.contacts_SOI__c = con.SOI__c;
        }
    }
}

 

Final working test

@istest
private class MySOITestClass{

  static testMethod void myUnitTest(){
    Contact con = new Contact
 (
            Lastname = 'Test'
 ); 
            // fill in all other required fields fields
   
   insert con;
    Task taskObj = new Task(
            WhoId = con.Id,
            Subject = 'CVM',
            Status = 'In Progress',
            Priority = 'High');
              // fill in all other required fields fields
    
    Test.startTest();
        insert taskObj;
        //verify if the trigger did the job  
        System.assertEquals(Con.SOI__c,[SELECT contacts_SOI__c FROM Task WHERE
Id=:taskObj.Id].contacts_SOI__c);      
    Test.stopTest();
  }                             
}

 

All Answers

izayizay

Hi Brittanie,

 

I struggled to understand Maps my first few times writing triggers too. I've written the trigger you need to update all tasks related to a contact(WhoId) whith the value in SOI__c.

 

Trigger TaskBefore on Task(before insert, before update){
    
    //The map... key:Id, value: list of tasks
    Map<Id, List<Task>> whoIdsMap = new Map<Id, List<Task>>{};
    
    for(Task t : trigger.new)
        //If this task has a WhoId...
        if(t.WhoId != null){
            //Need to add contact id(WhoId) and task list to map
            //Check if the map contains the WhoId as key
            if(!whoIdsMap.containsKey(t.WhoId)){//If not found
                //Create temporary list for tasks
                List<Task> temp = new List<Task>();
                //Add current task to temp list
                temp.add(t);
                //Put WhoId, List<Task> to map
                whoIdsMap.put(t.WhoId, temp);
            }else{//If found
                //Add current task to existing list of tasks under this WhoId
                whoIdsMap.get(t.WhoId).add(t);
            }
        }
    }
    
    //Get contacts and iterate through contacts...
    for(Contact con : [Select Id, Name,SOI__c from Contact where Id in :whoIdsMap.keySet()]){
        //Get the tasks for this contact and iterate through them
        //Update field value
        for(Task t :whoIdsMap.get(con.Id)){
            t.contacts_SOI__c = con.SOI__c;
        }
    }        
}

 

If you get any errors when saving check for misspellings. Hope this helps!

BrittanieBrittanie

Recieveing 

Error: Compile Error: unexpected token: for at line 26 column 4

Any ideas?

SF94108SF94108

You have an extra curly bracket at line 23!

 

remove it and that shoudl do the trick.

Izay IrizarryIzay Irizarry

Yes, I can see I missed a { after:

 

for(Task t :trigger.new){

 

Add that curly bracket and the code should compile fine.

Izay IrizarryIzay Irizarry

Here is the complete code:

 

Noticed also had another error:

 

Map<Id, List<Task>> whoIdsMap = new Map<Id, List<Task>>{};

 

Map<Id, List<Task>> whoIdsMap = new Map<Id, List<Task>>();

 

Should be good now!

 

Trigger TaskBefore on Task(before insert, before update){
    
    //The map... key:Id, value: list of tasks
    Map<Id, List<Task>> whoIdsMap = new Map<Id, List<Task>>();
    //For each task being inserted, updated
    for(Task t : trigger.new){
        //If this task has a WhoId...
        if(t.WhoId != null){
            //Need to add contact id(WhoId) and task list to map
            //Check if the map contains the WhoId as key
            if(!whoIdsMap.containsKey(t.WhoId)){//If not found
                //Create temporary list for tasks
                List<Task> temp = new List<Task>();
                //Add current task to temp list
                temp.add(t);
                //Put WhoId, List<Task> to map
                whoIdsMap.put(t.WhoId, temp);
            }else{//If found
                //Add current task to existing list of tasks under this WhoId
                whoIdsMap.get(t.WhoId).add(t);
            }//End if else
        }//End if
    }//End for
    
    //Get contacts and iterate through contacts...
    for(Contact con : [Select Id, Name,SOI__c from Contact where Id in :whoIdsMap.keySet()]){
        //Get the tasks for this contact and iterate through them
        //Update field value
        for(Task t :whoIdsMap.get(con.Id)){
            t.contacts_SOI__c = con.SOI__c;
        }//End for
    }//End for
}//End trigger

 

BrittanieBrittanie

apparently I'm not ment to get this to work :( 

 

Currently getting the following error but I swear these fields exist.

 

Error: Compile Error: Invalid field contacts_SOI__c for SObject Task at line 30 column 13

izayizay

Hi Brittanie,

 

Look in your custom activity fields to make sure that the API name for the field is spelled correctly. If that is not the case then, I'm not sure what could be the problem.

 

Izay

BrittanieBrittanie

final working code

 

Trigger Task_SOI on Task(before insert, before update){
   
   
    Map<Id, List<Task>> whoIdsMap = new Map<Id, List<Task>>();
    
    for(Task t : trigger.new){
       
        if(t.WhoId != null){
            
            if(!whoIdsMap.containsKey(t.WhoId)){
                
                List<Task> temp = new List<Task>();
                
                temp.add(t);
               
                whoIdsMap.put(t.WhoId, temp);
            }else{
                
                whoIdsMap.get(t.WhoId).add(t);
            }
        }
    }
   
    
    for(Contact con : [Select Id, Name,SOI__c  from Contact where Id in :whoIdsMap.keySet()]){
        
        for(Task t :whoIdsMap.get(con.Id)){
            t.contacts_SOI__c = con.SOI__c;
        }
    }
}

 

Final working test

@istest
private class MySOITestClass{

  static testMethod void myUnitTest(){
    Contact con = new Contact
 (
            Lastname = 'Test'
 ); 
            // fill in all other required fields fields
   
   insert con;
    Task taskObj = new Task(
            WhoId = con.Id,
            Subject = 'CVM',
            Status = 'In Progress',
            Priority = 'High');
              // fill in all other required fields fields
    
    Test.startTest();
        insert taskObj;
        //verify if the trigger did the job  
        System.assertEquals(Con.SOI__c,[SELECT contacts_SOI__c FROM Task WHERE
Id=:taskObj.Id].contacts_SOI__c);      
    Test.stopTest();
  }                             
}

 

This was selected as the best answer