Create an Indicator Badge Apex Service
We've got our component up and running in Lightning Experience, and an Apex controller connected to it. Now we need to connect our component to our custom metadata—and we'll do that by adding a service in Apex and connecting it with the code we've already written.
Create the Indicator Badge Service class
- Click the gear icon
(
), then select Developer Console.
- Click File > New > Apex Class.
- Name the Apex class
INDICATOR_Service
. - Replace the generated code with:
public class INDICATOR_Service { public static List<String> getFieldsToQueryForObject(String objName){ Set<String> targetFields = new Set<String>(); for(Indicator_Badge__mdt i: [SELECT Related_Field__r.QualifiedApiName FROM Indicator_Badge__mdt WHERE Object__r.QualifiedApiName = :objName]){ targetFields.add(i.Related_Field__r.QualifiedApiName); } return new List<String>(targetFields); } public static List<Indicator> getIndicatorBadgesForObject(SObject sobj){ List<Indicator> recordIndicators = new List<Indicator>(); for(Indicator_Badge__mdt indicator: [SELECT MasterLabel, Badge_Color__c, Comparison_Value__c, Comparison_Type__c, Badge_Icon_Name__c, Related_Field__r.QualifiedApiName FROM Indicator_Badge__mdt WHERE Object__r.QualifiedApiName = :sobj.getSObjectType().getDescribe().getName()]){ recordIndicators.add(evaluateIndicator(indicator, sobj)); } return recordIndicators; } private static Indicator evaluateIndicator(Indicator_Badge__mdt i, SObject sobj){ Object field = sobj.get(i.Related_Field__r.QualifiedApiName); Boolean isEnabled = false; if(i.Comparison_Type__c == 'Use Boolean Value of Field'){ isEnabled = (Boolean)field; } else if(i.Comparison_Type__c == 'Contains'){ isEnabled = (String.valueOf(field)).contains(i.Comparison_Value__c); } else if(i.Comparison_Type__c == 'Not Blank or Null'){ isEnabled = String.isNotBlank(String.valueOf(field)); } else if(i.Comparison_Type__c == 'Blank or Null'){ isEnabled = String.isBlank(String.valueOf(field)); } else if(i.Comparison_Type__c == 'Greater or Equal'){ isEnabled = (Decimal)field >= Decimal.valueOf(i.Comparison_Value__c); } else if(i.Comparison_Type__c == 'Less or Equal'){ isEnabled = (Decimal)field <= Decimal.valueOf(i.Comparison_Value__c); } if(isEnabled){ return new Indicator(i.Badge_Icon_Name__c, i.Badge_Color__c, i.MasterLabel); } else { return null; } } //inner class, creating our 'Indicator' object and attributes public class Indicator{ //first, the attributes: @AuraEnabled public String icon {get; set;} @AuraEnabled public String color {get; set;} @AuraEnabled public String label {get; set;} //then, our object: public Indicator(String icon, String color, String label){ this.icon = icon; this.color = color; this.label = label; } } }
- Click File > Save.
Code Highlights:
- The INDICATOR_Service class is, as the name suggests, a service for querying and processing Indicator Badge records. It also contains an inner class called Indicator, which acts like a custom object in memory. In other words, it exists for as long as someone is viewing a record and working with it, but no longer. No cluttering up the database! This inner class is the actual object our Lightning components use (hence the @auraEnabled annotations).
- The
getIndicatorBadgesForObject
method runs a query for Indicator Badge custom metadata records, based upon the sObject type, which is passed in as a parameter. - The
getFieldsToQueryForObject
method assembles fields needed from a particular record in Salesforce, based on the "Related Field" values found on any associated Indicator Badge records. - The
evaluateIndicator
method is where the magic (aka business logic!) happens: it uses values of a particular record to decide if an indicator badge should display.
Add Access to the Indicator Service into the Indicator Controller
- In the Developer Console, navigate to the INDICATOR_Controller Apex class.
- Replace the current markup with this code:
public class INDICATOR_Controller { private static SObject sobj; @AuraEnabled public static String getSObjectLabel(String sObjName){ String label = Schema.getGlobalDescribe().get(sObjName).getDescribe().getLabel(); return label; } @AuraEnabled public static List<INDICATOR_Service.Indicator> getIndicators(String recId, String objectName){ getSObject(recId, objectName); if(sobj != NULL){ List<INDICATOR_Service.Indicator> indicators = INDICATOR_Service.getIndicatorBadgesForObject(sobj); return indicators; } else { return null; } } public static void getSObject(String recId, String objectName){ List<String> fNames = INDICATOR_Service.getFieldsToQueryForObject(objectName); if(fNames.size() > 0){ String query = 'SELECT Id,'+ String.join(fNames,',')+' FROM '+ objectName +' WHERE Id =\''+ recId +'\' LIMIT 1'; List<SObject> results = Database.query(query); if(results.size() == 1){ sobj = results[0]; } } } }
- Click File > Save.
Code Highlights:
- The
@AuraEnabled
method in our INDICATOR_Controller coordinates the fetching and returning of Indicator objects (the one defined in-memory by our INDICATOR_Service) for a specific record. - The
getSObject
method uses a dynamic query to grab the relevant fields for the record.