While working-on/playing with the Build a Restaurant-Locator Lightning Component Trailhead, I wanted to develop a more clever (possibly read over-engineered) way of selecting address from either the Contact or the Account.
I was hoping I could put the input Id into a wrapper and then use an overloaded method (instead of conditional logic) to return the correct address.
So, I have this (working) code to wrap the Id:
public class SObjectIdHelper {
public SObjectIdHelper.SObjectId getIdFor(String sObjectType, Id recordId) {
if (sObjectType == 'Account') {
return new AccountId(recordId);
} else if (sObjectType == 'Contact') {
return new ContactId(recordId);
}
throw new SObjectIdHelperException('Unsupported SObjectType: ' + sObjectType);
}
public virtual class SObjectId {
public Id id {get; private set;}
public SObjectId(Id id){
this.id = id;
}
}
public class AccountId extends SObjectId {
public AccountId(Id id){
super(id);
}
}
public class ContactId extends SObjectId {
public ContactId(Id id){
super(id);
}
}
}
And I have this address helper:
public class ITA_AddressHelper {
ITA_AccountHelper accountHelper;
ITA_ContactHelper contactHelper;
public ITA_AddressHelper(ITA_AccountHelper accountHelper, ITA_ContactHelper contactHelper) {
this.accountHelper = accountHelper;
this.contactHelper = contactHelper;
}
public ITA_AddressHelper() {
this(new ITA_AccountHelper(), new ITA_ContactHelper());
}
public String getAddress (SObjectIdHelper.AccountId recordId) {
return this.accountHelper.selectLocation(recordId.id);
}
public String getAddress (SObjectIdHelper.ContactId recordId) {
return this.contactHelper.selectLocation(recordId.id);
}
public String getAddress (SObjectIdHelper.SObjectId recordId) {
throw new ITA_AddressHelperException('Unsupported SObject Id Type');
}
}
My InTheArea class contains this method:
private String request(String searchTerm, String sObjectType, Id recordId) {
try {
SObjectIdHelper.SObjectId typedId = this.sObjectIdHelper.getIdFor(sObjectType, recordId);
return this.yelpWrapper.request(searchTerm, this.addressHelper.getAddress(typedId));
}
catch (Exception ex) {
return '{' +
'"error" : "This component cannot be used on this page type: ' + ex.getMessage() + '"'
+ '}';
}
}
Unfortunately, this will fail because SFDC doesn't seem to leverage that typedId
is actually an instance of either SObjectIdHelper.AccountId
or SObjectIdHelper.ContactId
.
I can make this work like
public class ITA_AddressHelper {
ClassHelper classHelper;
ITA_AccountHelper accountHelper;
ITA_ContactHelper contactHelper;
private Map<String, ProvidesLocation> locationProviderByIdTypeMap;
public ITA_AddressHelper(ClassHelper classHelper, ITA_AccountHelper accountHelper, ITA_ContactHelper contactHelper) {
this.classHelper = classHelper;
this.accountHelper = accountHelper;
this.contactHelper = contactHelper;
locationProviderByIdTypeMap = new Map<String, ProvidesLocation>{
'AccountId' => accountHelper,
'ContactId' => contactHelper
};
}
public ITA_AddressHelper() {
this(new ClassHelper(), new ITA_AccountHelper(), new ITA_ContactHelper());
}
public String getAddress (SObjectIdHelper.SObjectId recordId) {
String idType = classHelper.getNameFor(recordId);
ProvidesLocation locationProvider = locationProviderByIdTypeMap.get(idType);
if (locationProvider != null){
return locationProvider.selectLocation(recordId.id);
} else {
throw new ITA_AddressHelperException('Unsupported SObject Id Type');
}
}
}
But now I need to mess around with maps and getting the wrapper class name.
Is there a better way to make this work?