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.DataRow
options.
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