APEX
Using Custom Metadata Type for App configuration
Custom metadata type object is customisable, deployable, packageable and upgradeable application metadata.
- It can be really useful to use them as configurable settings for our components.
There are many use cases where we want or need a certain “placeholder” functionality or we want to have a certain configurable settings functionality per installation of your app.
Always best to start with defining the use case carefully to understand :
- Who would need to change the settings – Profile / User or any Admin like ?
- What will be the user experience of the Admin when changing those settings ? Would a user change those values frequently ?
- Would it be secure to store values in those settings ? Storing Credentials from some sort always have some more consideration to it.
Answering those questions will help you decide which “tool” or object type to use.
Metadata Type – MDT – Might look to some as somehow a more modern evolution of “Custom Settings”. which might be true.
Unlike custom settings, the main benefits I’ve seen are :
- They are deployable and package-able
- They have more data field types – like those cool Metadata relationship Entity and Field picklist
- It’s Traceable (Setup audit trail history)
- Can have validation rules
- They have page layouts 🙂
But on the other hand :
- Harder to create/update/delete settings programatically – this will require Metadata deploy and not a simple Apex script.
- You can have up to 200 in an org – This number includes all types developed in the org and installed from managed and unmanaged packages.
To get access to MDT records you can simply query the object.
CUSTOMOBJECT__mdt[] settings = [SELECT MasterLabel,
QualifiedApiName,
DeveloperName,
Field__c
FROM CUSTOMOBJECT__mdt];
Then we can use this Metadata Record to define and configure elements within our app.Â
Adding Metadata Type Records as Design Attribute picklist
- Create Apex class that extend
VisualEditor.DynamicPickList - Query for the Metadata Records and return
VisualEditor.DataRowoptions.
public with sharing class UIMetadataPicklist extends VisualEditor.DynamicPickList {
public override VisualEditor.DataRow getDefaultValue(){
VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('Default', 'Default',true);
return defaultValue;
}
public override VisualEditor.DynamicPickListRows getValues() {
VisualEditor.DynamicPickListRows allPicklistValus = new VisualEditor.DynamicPickListRows();
// VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('None', 'none',true);
// allPicklistValus.addRow(defaultValue);
List<Settings__mdt> allActiveRecords = getAllDataRecords();
for(Settings__mdt rec : allActiveRecords) {
VisualEditor.DataRow value = new VisualEditor.DataRow(rec.MasterLabel,rec.DeveloperName,false);
allPicklistValus.addRow(value);
}
return allPicklistValus;
}
private static List<Settings__mdt> getAllDataRecords() {
// Build custom Metadata query
return [SELECT MasterLabel, DeveloperName From Settings__mdt];
}
}
On your LWC .xml file
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="migrateDesignAttributeToLWC">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>Design Attribute in LWC</masterLabel>
<description>This component shows ability to populate an option list from Apex datasource </description>
<targets>
<target>lightning__RecordPage</target>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage,lightning__AppPage,lightning__HomePage">
<property name="metadataRecord" label="Metadata Record" type="String" datasource="apex://UIMetadataPicklist" description="Configuration Attributes Stored in Custom Metadata Type"/>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
Inside your JS file make sure you expose an @api property named metadataRecord.
- In case you using Aura add the following on your design file:
<design:component label="Configurable Component">
<design:attribute name="metadataRecord" label="Metadata Record" datasource="apex://UIMetadataPicklist" description="Configuration Attributes Stored in Custom Metadata Type"/>
</design:component>
Storing key,value pair inside Custom Metadata Type
- This can be useful for Integration Parameters or Headers.Â
- Simply add one custom field on our mdt object and iterate and put in Map with the DeveloperName and the Value__c field value.Â
public static final Map<String, String> Settings;
static {
// Load the custom metadata records into a Map collection
Settings = new Map<String, String>();
for(Settings__mdt record : [ SELECT Id, DeveloperName, Value__c FROM Settings__mdt ]) {
Settings.put(record.DeveloperName, record.Value__c);
}
// Configurable NamedCredentials per environment
public static String getNamedCredential() {
return Settings.get('NamedCredentialKey');
}
}
Those are just a few use cases but I’m sure there are plenty of them and the best thing that with Custom Metadata Type Records – we can simply deploy our default settings to the Users and they can change it later as they wish.Â
Resources :
- Custom Metadata Types – Documentation



