1

Problem

I'm working with custom meta data records. We have email subscription recipes for various contacts in the org.

The admins need to be able to add custom fields to these recipes without requesting a developer to update the code. I wrote the apex code to handle this scenario. However, Checkbox field types causing errors for existing metadata recipe records.

I noticed that the default value does not work. For example, on the custom records that already exist, the admin would have "re-save" the custom metadata records so that the field type value does not come through the trigger as a null value. This is because the default values for example, unchecked or checked do not carry over to the existing metadata records, and so when they run the trigger I get an error of "the data type is null and does not match the required field type".

Question

Is my only option here to resave all custom metadata type records? Or is there a configuration I'm missing when creating the custom field? Maybe there is a way to make the apex code handles this scenario?

Thanks for the help!

Apex method

public with sharing class RecipeMaker {
    public static Map<String, Contact_Subscription_Recipes__mdt> recipeValues = Contact_Subscription_Recipes__mdt.getAll();

public static void setRecipeValues(Contact c,  String recipeNumber){
    
    List<String> exceptionValues = new List<String>{'MasterLabel', 'Label', 'Language', 'QualifiedApiName', 'NamespacePrefix', 'DeveloperName', 'Id' };
    Map<String, Object > mapValues = Contact_Subscription_Recipes__mdt.getInstance('Recipe_' + recipeNumber).getPopulatedFieldsAsMap();
    Map<String, Object > fieldValues = new Map<String, Object>();
    
    for (String k : mapValues.keySet()){
        if (!exceptionValues.contains(k)){
    // build query
            System.debug('Field/Key = ' + k + '--> ' + 'value ' + mapValues.get(k));
        
            
            fieldValues.put(k, mapValues.get(k));
        }
    }
    
    
    for (String k : fieldValues.keySet()){
            Boolean f = false; 
            System.debug('Setting for update --> ' + k);
            c.put(k, fieldValues.get(k) );
            System.debug(c.get(k));
        }
        
    }


}

1 Answer 1

1

Default values are never applied to existing records. They are always set to an empty/null state. However, this seems surprising, because checkboxes cannot contain a null value. They are always checked or unchecked, and the default is to be not checked. That said, I think the easiest way to work around this problem is to describe each field, and if it has a DisplayType of BOOLEAN, then compare the field value to true. This would convert the nulls to false.

Here's a suggested update:

Map<String, sObjectField> contactFieldMap = sObjectType.Contact.fields.getMap();
for (String k : fieldValues.keySet()){
    if(contactFieldMap.get(k).getDescribe().getType() == DisplayType.BOOLEAN) {
        c.put(k, fieldValues.get(k) == true);
    } else {
        c.put(k, fieldValues.get(k) );
    }
}
4
  • That makes sense. Making records update like that would be a massive background whenever a field was added. I attempted your logic here prior to posting, but it did not work. I was just checking for null values and then updating the map to have a false value. But the value did not seem to take. I'll attempt again.
    – thinker
    Feb 23, 2022 at 18:55
  • 1
    @thinker You can't put false in to any kind of field, which is why my design checks first if the field is a checkbox. If not a checkbox, we pass in whatever we are given, which may still be null.
    – sfdcfox
    Feb 23, 2022 at 19:39
  • They are all checkboxes. So it shouldn't really matter, right.
    – thinker
    Feb 23, 2022 at 19:44
  • ah, I see you're using a contact field map
    – thinker
    Feb 23, 2022 at 19:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .