You need to sign in to do that
Don't have an account?
Brian Nolau 2
Question on complex APEX code that shows how to run after insert and after update triggers?
So i'm about 50% into my Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition) book and I'm stuck on the below code. I provide a text version under the image. The below code has no problems. When I create a new task nothing happens though and if I create a task with a Contact it has an issue that says: TaskTrigger: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.TaskTrigger: line 14, column 1
Text version of the code from Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition):
trigger TaskTrigger on Task (after insert, after update) {
switch on Trigger.operationType {
when AFTER_INSERT {
Set<Id> contactIds = new Set<Id>();
For(Task t: Trigger.new) {
If(t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
contactIds.add(t.WhoId);
}
}
Map<Id, Contact> contactMap = new Map<Id, Contact> ([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in: contactIds]);
For(Task t :Trigger.new) {
If(contactMap.containsKey(t.WhoId)) {
contactMap.get(t.WhoId).No_of_Open_Tasks__c += 1;
}
}
Update contactMap.values();
}
when AFTER_UPDATE {
Set<ID> contactIds = new Set<Id>();
For(Task t : Trigger.new) {
If(t.IsClosed && !Trigger.oldMap.get(t.Id).IsClosed && t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
contactIds.add(t.WhoId);
}
}
Map<Id, Contact> contactMap = new Map<Id, Contact>([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in :contactIds]);
For(Contact con : contactMap.values()) {
Con.No_of_open_tasks__c = 0;
}
For(AggregateResult ar : [SELECT WhoId, Count(Id) total FROM Task WHERE IsClosed = false AND WhoId in :contactIds GROUP BY WhoID]) {
String who = String.Valueof(ar.get('WhoId'));
Decimal total = (Decimal)(ar.get('total'));
contactMap.get(who).No_of_Open_Tasks__c = total;
}
update contactMap.values();
}
}
}
Text version of the code from Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition):
trigger TaskTrigger on Task (after insert, after update) {
switch on Trigger.operationType {
when AFTER_INSERT {
Set<Id> contactIds = new Set<Id>();
For(Task t: Trigger.new) {
If(t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
contactIds.add(t.WhoId);
}
}
Map<Id, Contact> contactMap = new Map<Id, Contact> ([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in: contactIds]);
For(Task t :Trigger.new) {
If(contactMap.containsKey(t.WhoId)) {
contactMap.get(t.WhoId).No_of_Open_Tasks__c += 1;
}
}
Update contactMap.values();
}
when AFTER_UPDATE {
Set<ID> contactIds = new Set<Id>();
For(Task t : Trigger.new) {
If(t.IsClosed && !Trigger.oldMap.get(t.Id).IsClosed && t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
contactIds.add(t.WhoId);
}
}
Map<Id, Contact> contactMap = new Map<Id, Contact>([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in :contactIds]);
For(Contact con : contactMap.values()) {
Con.No_of_open_tasks__c = 0;
}
For(AggregateResult ar : [SELECT WhoId, Count(Id) total FROM Task WHERE IsClosed = false AND WhoId in :contactIds GROUP BY WhoID]) {
String who = String.Valueof(ar.get('WhoId'));
Decimal total = (Decimal)(ar.get('total'));
contactMap.get(who).No_of_Open_Tasks__c = total;
}
update contactMap.values();
}
}
}
trigger TaskTrigger on Task (after insert, after update) {
switch on Trigger.operationType {
when AFTER_INSERT {
Set<Id> contactIds = new Set<Id>();
For(Task t: Trigger.new) {
If(t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
contactIds.add(t.WhoId);
}
}
Map<Id, Contact> contactMap = new Map<Id, Contact> ([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in: contactIds]);
For(Task t :Trigger.new) {
If(contactMap.containsKey(t.WhoId)) {
contactMap.get(t.WhoId).No_of_Open_Tasks__c += 1;
}
}
Update contactMap.values();
}
when AFTER_UPDATE {
Set<ID> contactIds = new Set<Id>();
For(Task t : Trigger.new) {
If(t.IsClosed && !Trigger.oldMap.get(t.Id).IsClosed && t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
contactIds.add(t.WhoId);
}
}
Map<Id, Contact> contactMap = new Map<Id, Contact>([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in :contactIds]);
For(Contact con : contactMap.values()) {
Con.No_of_open_tasks__c = 0;
}
For(AggregateResult ar : [SELECT WhoId, Count(Id) total FROM Task WHERE IsClosed = false AND WhoId in :contactIds GROUP BY WhoID]) {
String who = String.Valueof(ar.get('WhoId'));
Decimal total = (Decimal)(ar.get('total'));
contactMap.get(who).No_of_Open_Tasks__c = total;
}
update contactMap.values();
}
}
does anyone have an APEX book that they recommend I hate reading a book and the author goes insane with power 100 pages in
Hi Brian, how did you manage to solve it? I am on the same page of the book right now... same error:
TaskTrigger: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.TaskTrigger: line 25, column 1
I populate the "No of open task" field using a List instead of a Map but as the writer explains, this only works if you insert one task per contact
I will keep on trying
Hi Brian, I think the default value of 0 is missing, that is the reason for the error to show up
I tried setting up the value of "No_Of_Open_Tasks__c" to 0 and then it works
To clarify (for anyone reaching this matter), this would not work:
Integer tasks;
tasks += 1;
As "tasks" is stated as null:
But this would:
Integer tasks = 0;
tasks += 1;
system.debug(tasks);
Took me a while to find it out, I am learning APEX too 😉
Have a nice weekend