This is technically my first "production" trigger and I've spent a lot of time on this so far.

Basic premise is that I have the task object and when the Related To (WhatId) is facing a particular record type (custom object supplier__c), I want to fill the supplier__c lookup field of that new task with the value in the Related To field. This will need to account for null values or other object types in the Related To field.

Please excuse all the sys debugs / comments. I added these for my own clarity.

// sets Supplier__c as = to WhatId when WhatId is a Supplier Type
trigger setTaskSupplier on Task (before insert, before update) {
    system.debug('----->>> TRIGGER START');
    // instantiate list:
    list<Task> objList = new list<Task>();
    // instantiate recordtype:
    Id devRecordTypeId = Schema.SObjectType.Task.getRecordTypeInfosByName().get('Payment Task').getRecordTypeId();
    system.debug('----->>> devrecordtypeid: ' + devRecordTypeId);

    //add task to list if meets criteria
    for(Task obj : trigger.new){
            if ( String.valueof(obj.WhatId).startsWith('a1m') && obj.RecordTypeId == devRecordTypeId ) { 
                objList.add(new Task(Id = obj.id));

            //set update on tasks in list
            for (Task upd : objList){
            upd.Supplier__c = upd.WhatId;
            system.debug('----->>> TRIGGER updates task id: ' + upd.Id);

            //perform update:
            update objList;
            system.debug('----->>> TRIGGER END');

There are indeed some problems with your code.

You don't need to instantiate a new list of task. You can update the current task record inside your loop because you are inside a before trigger. Any change applied to the records is saved to the database.

Also, you can detect the type of a record using his Id without needing to check the prefix of the Id with the getSobjectType() method

So your code will be highly simplified:

trigger setTaskSupplier on Task (before insert, before update) {
    Id devRecordTypeId = Schema.SObjectType.Task.getRecordTypeInfosByName().get('Payment Task').getRecordTypeId();

    for(Task obj : trigger.new){
        if(obj.WhatId != null){
            if (obj.WhatId.getSobjectType() == Schema.Supplier__c.SObjectType && obj.RecordTypeId == devRecordTypeId ) { 
                obj.Supplier__c = obj.WhatId;
  • You should also do a null check on WhatId first, or your code will throw an error if the Task has no WhatId specified (for example, a Task directly on a Contact). – Roti Oct 30 '19 at 16:36
  • Thanks @Roti ! Didn't think of that. – Martin Lezer Oct 30 '19 at 16:37
  • Np. Another thing for @gscott, you didn't specify if Supplier__c should get cleared out if the WhatId is not a Supplier__c record or not. If so, then in the else section of either of the two if statements, you will need to clear out the Supplier__c field. The ideal solution would be to add a flag for something like whatIdIsSupplier, or something like that, and then after the if statements, if whatIdIsSupplier is false, set obj.Supplier__c to null. This is only if you need to clear it out in that scenario. – Roti Oct 30 '19 at 16:45

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.