1

I've been trying for many hours to find the correct syntax in the documentation and via other searches in Google to get some dynamic code to run. Hopefully someone here will be able to provide the insight and proper syntax that I'm clearly not grasping. Here's some of my code that should illustrate what I'm trying to accomplish.

public list<sObject> generateGlobal_Id_Generator(list<sObject> TheRecords){

    if(!TheRecords.isEmpty()){ 
        system.assertEquals(TheRecords.getsObjectType,TheRecords[0].sObjectType());
        Schema.DescribesObjectResult DescribeResult = TheRecords[0].sObjectType.getDescribe();
        Schema.SObjectType objectType = DescribeResult.getSobjectType();
        getGlobal_Ids(TheRecords, objectType);

    }else{
        Throw CustomIdGenerationListIsEmptyException e;
    }
}

public list<sObject> getGlobal_Ids(list<sObject> TheRecords, Schema.SObjectType objectType){

    // I'm getting "invalid type sObjectType/invalid object error" depending on the coding
    // Below is what I want to do:

    for(SObject Record:TheRecords){
        Record.Global_Id__c = getGlobal_Id(ObjectName, Id.ValueOf(Record.Id));

       // the line above calls another function 'getGlobal_Id' & assigns results
    }   
    return TheRecords;
}

In the area above where I'm having problems, I've tried using sObject, string ObjectName = DescribeResults.getLocalName() and objectName = getPrefixedName(objectName);. (this is in a managed package). I've also tried using system.AssertEquals(ToGenerate.getType(),objectType); to set the equivalence between the list and object record.

There are 6 different objects that will use this function to dynamically generate this field value. What am I missing to make this work? Its as though I can't seem to 'cast' it properly to get it to allow me to iterate and also access field values as well.

Edit:

It seems that at the root of the problem I'm having is in casting the sObject to a string and back (esp when in a list). That seems to be what's preventing me from iterating on the object name (can't do it in string form nor as plain sObject). It seems I need to quickly determine the name of the sObject and maintain that relationship using some kind of particular syntax that I've seen before, but can't recall exactly what it is.

  • sObjectType.getDescribe().fields.getMap() ? salesforce.stackexchange.com/questions/47731/… – Phil Hawthorn Oct 23 '16 at 19:19
  • @PhilHawthorn Ahhh, so without the fieldmap, I won't be able to access the fields! Makes perfect sense to me Phil! Thanks. Will see where that leads me. – crmprogdev Oct 23 '16 at 19:30
  • 1
    crmprogdev -- what is the goal of your code? There may be a simpler way to do it but I'm not sure of your objective – cropredy Oct 23 '16 at 23:52
  • @cropredy Good question! The goal is to pass an object record (preferably in list form, but I'll begin with a single record), have the code recognize the object's type, validate it, and then pass the SF recordId and custom object name to another method that creates a 78 character string Id and assigns it to a custom field called Global_Id__c that appears on 6 different custom objects. It will ultimately be called from a service on afterInsert. – crmprogdev Oct 24 '16 at 0:40
  • 1
    (1) someSobj.getSobjectType() returns the Type of the sobject; (2) someSobj.getSobjectType().getDescribe().getName() returns the object's name; and (3) someSobj.get('ID') gets the ID field's value without having to cast into a concrete type. What am I missing? – cropredy Oct 24 '16 at 18:01
1

Here's my stab at what I think you're trying to do:

public class GlobalIds {

    public list<sObject> generateGlobal_Id_Generator(list<sObject> TheRecords){

        if(!TheRecords.isEmpty()){ 
            // I guess you mean to check that each element matches the sObjectType
            // reported by the list, so...
            for(sObject Record : TheRecords) {
                system.assertEquals(TheRecords.getSObjectType(),Record.getSObjectType());
            }
            return getGlobal_Ids(TheRecords, TheRecords[0].getSObjectType());

        }else{
            Throw new CustomIdGenerationListIsEmptyException();
        }
    }

    public list<sObject> getGlobal_Ids(list<sObject> TheRecords, Schema.SObjectType objectType){

        for(SObject Record:TheRecords){
            // Using .put() instead of assignment because it's a generic sObject
            // Using objectType.getDescribe().getName() because we've already checked that
            // the sObjectType is correct
            Record.put('Global_Id__c', getGlobal_Id(objectType.getDescribe().getName(), Id.ValueOf(Record.Id)));
        }   
        return TheRecords;
    }

    // Mocks so that I can compile this
    public String getGlobal_Id(String objName, Id objId) {
        return objName + objId;
    }
    public class CustomIdGenerationListIsEmptyException extends Exception {

    }    
}

I'm not sure that I can explain much more than just what's in the comments, but happy to answer questions on it. Or be told that I missed the point ;-)

  • @Aiden, you've outlined the general approach of what I'm trying to do. I think you're on target with the put approach. system.assertEquals(TheRecords.getSObjectType(),Record.getSObjectType()); this doesn't validate sObjectType. It only asserts that the list and record are the same & doesn't get the record's non-namespaced SObjectType to pass into the function (I can handle the namespace differently though) and validate the type in the getGlobal_Id method. Will try this approach to see if can make it work & let you know. Thanks for the effort & ideas! – crmprogdev Oct 24 '16 at 11:59
  • Hmm... what validation are you expecting to do on the sObjectType? In my mind, it is what it is. But there must be something more that you have in mind. I have done a load of work with one of my packages processing objects from installed orgs, so I might be able to help if I can figure out what you're getting at. – Aidan Oct 24 '16 at 14:25
  • I simply want to make certain that the list of objects passed in are the correct type before I create "global Ids" that use a different typing method which will be assigned using an enum. If they're not, then I'll throw an exception. These records will be passed between MANY different Salesforce Orgs where the SF id will be unique and have a different local type in each one. (don't ask me to explain further - NDA) – crmprogdev Oct 24 '16 at 16:55
1

Moving comments to answer

someSobj.getSobjectType() returns the sobjectType of the sobject (e.g. Account.SObjectType);

someSobj.getSobjectType().getDescribe().getName() returns the object's name including namespace. Use getLocalName() to omit namespace;

someSobj.get('ID') gets the ID field's value without having to cast into a concrete type.

These should be enough to get you from an arbitrary list of sobjects to an ID plus sobject name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.