3

I've created a method to extract a specific field from a list of sObjects, and since it accepts any sObject, I return a list of Object too, since field types can vary.

So the method is as follows:

public static List<Object> getFieldFromSobjectList(List<SObject> objects, String field_name) {
    List<Object> result = new List<Object>();
    for (SObject obj : objects) {
        try {
            result.add(obj.get(field_name));
        } catch (Exception e) {
            // ... shh bb is ok
        }
    }
    return result;
}

The method returns a list of objects and I'm trying to convert the result to a list of ids, using casting:

List<Id> list_of_ids = (List<Id>) Utils.getFieldFromSobjectList(list_of_objects, 'Id');

Even though this code can be compiled, at runtime it throws me an error:

System.TypeException: Invalid conversion from runtime type List<ANY> to List<Id>
3
  • Not sure why you're getting this error (or why it's saying that you're trying to cast a List<ANY> instead of a List<Object>), but as a workaround, have you tried iterating over the resulting list and casting individual objects as Id instead of trying to cast the entire list?
    – Derek F
    Commented Jan 25, 2017 at 15:47
  • I haven't. I was hoping to reduce lines of code with this approach... getting the list of what I need with one line. Commented Jan 25, 2017 at 15:54
  • @DerekF I tried to get the list to a variable and then converting it to a list of Ids, and it gave me the same error. Commented Jan 25, 2017 at 16:03

3 Answers 3

2

Here is my Utility class that does this with props to @sfdcfox

//  ------------------------------------------------------
//  getIdSetFromField   : gets a set of Ids from a list of sobjects in <field>
//  ------------------------------------------------------
public static Set<ID> getIdSetFromField(SObject[] records, SObjectField fieldname) {
    return new Set<ID> ((List<ID>) getValListFromField(List<ID>.class, records, fieldname));
}

//  --------------------------------------------------------
//  getValListFromField     : Returns a list of field values from a list of sobjects; ref: http://salesforce.stackexchange.com/a/64949/2602
//                          : Usage Ex: Decimal[] amountList = (Decimal[])Util.getValListFromField(Decimal[].class,Trigger.new,Opportunity.Amount);
//  --------------------------------------------------------
public static Object[] getValListFromField(Type resListType, SObject[] records, SObjectField fieldname) {
    Object[] res    = (Object[])resListType.newInstance();
    for (SObject sObj: records)
        res.add(sobj.get(fieldname));
    return res; 
}

Usage

set<ID> ids = Util.getIdSetFromField(Trigger.new,Opportunity.AccountId);

or, if you want a list

ID[] ids = new List<ID>(Util.getIdSetFromField(Trigger.new,Opportunity.AccountId));
1

It appears to me that you've not typed the sObject to retrieve it's name too which may be causing your issue since you're retrieved the field name. If you did that, you could return the list<sObject Name> which would have the Ids instead of just the field_name.

6
  • 1
    From what I understood with the SObject Class documentation, I can use the class' .get(field) method to retrieve the object's field value. I'm not sure what you meant with "retrieve it's name too" Commented Jan 25, 2017 at 15:58
  • You've not done a Schema.sObjectType tokenA = object.getSObjectType(); where object is a single record, not a list. So, you've not "typed" the sObject you're working with.
    – crmprogdev
    Commented Jan 25, 2017 at 16:11
  • But I don't need to do that. The following code works just fine, for example: Account a = new Account(Name='Test'); Sobject obj = a; System.debug(obj.get('Name')); Commented Jan 25, 2017 at 16:18
  • That it does, but you've not passed Account to your Class. Add that kind of code to your class, and you'll be doing the kind of thing that I'm referring to though. You'll be validating the type just as though you were casting it.
    – crmprogdev
    Commented Jan 25, 2017 at 16:36
  • So basically you are saying that I need to pass another parameters to my method that identifies the type of object in the list (the sObjectType). Is that correct? Commented Jan 25, 2017 at 16:39
0

While get method returns string, you can collect list <string> and in end convert it to list of ids:

list<String> strIds = new list<String>{'001M000000vs9Mh','001M000000vs9Mh'};
list<id> myIds = new list<id>();
myIds.addall((list<id>)strIds);
system.debug(myids);

For Integer you have to convert each value implicitly:

list<String> strIds = new list<String>{'150','123'};
list<integer> myInts = new list<integer>();
for (String id :strIds){
    myInts.add(integer.valueof(id));
}
system.debug(myInts);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .