2

So, I'm getting the values of the properties of a custom sObject in my org, in an Apex method. So, this is how it works, basically I receive via parameter a list of strings that are the fields that I need to fetch from the sObject. So, the process is this:

for(Item__c item : items){
  for(String field : fields){
     columns.add(String.valueOf(item.get(field)));
  }
}

The fields are being sent from my lightning component, in a way I can directly get them via sObject.get. The thing is, there is a field that is a lookup field (its called listing_type) and I don't know how can I access a field of the listing_type object. I can't access it directly like this, so how can I achieve this? It should be listing_type__r.name, but if I pass that to the item.get() it doesn't work.

3 Answers 3

4

You need to "follow the path", like this:

for(Item__c item: items) {
  for(String field: fields) {
    // Temp variable holds current spot in path
    sObject temp = item;
    // Break into parts; we need to escape . because split uses regex.
    String[] path = field.split('\\.');
    // While we have more path to follow, and current step isn't null...
    while(path.size()>1 && temp != null) {
      // Go to the next step
      temp = temp.getsObject(path.remove(0));
    }
    // Assuming we still have a current spot, we can get the end value here
    if(temp != null) {
      columns.add(String.valueOf(temp.get(path[0])));
    }
  }
}

You could even abstract this into a method if you think you might use it frequently.

3
  • so, I'm trying this one. Could I ask, what is the issue with the solution by user1228? is it likely to get errors , as there are no validations? Commented Mar 25, 2021 at 14:47
  • @joacoiudica user1228's code It could be made safe with ?. (the safe navigation operator), but it specifically assumes there is a one-object-deep path to follow. A solution like mine (and rahul's) supports unlimited depth. I also left out some validations (e.g. this code assumes the path is always valid), but you can choose which validations you want to implement, this is just the basic algorithm.
    – sfdcfox
    Commented Mar 25, 2021 at 14:56
  • thank you very much for the info! Commented Mar 26, 2021 at 18:45
2

You need to break up the field label to get the values from the Parent record. First you need to get the parent record using the getSObject method and then you can get the value of the parent field.

You can use the below method to dynamically get those values. Add the below method in your class.

public static string extractFieldValues(sObject sb, string fieldAPIName){
    string fvalue='';
    if(fieldAPIName.contains('.')){
        List<string> splitedFields = fieldAPIName.split('\\.');
        try{
            for(integer i=0;i<splitedFields.size()-1;i++){
                sb=sb.getSobject(splitedFields[i]);   
            }
            fvalue = string.valueof(sb.get(splitedFields[splitedFields.size()-1]));
        }catch(exception ex){
           system.debug('******exception while fetching fieldValues as relationship '+fieldAPIName+'  value is blank.'+ex.getmessage()); 
           fvalue='';
        }
        
    }else if(sb.get(fieldAPIName)!=null){
        fvalue = string.valueOf(sb.get(fieldAPIName));
    }
    return fvalue;
}

And use it like below.

for(Item__c item : items){
  for(String field : fields){
     columns.add(extractFieldValues(item, field));
  }
}

Refer this blog post for more details: Accessing Parent Field Values from sObjects in Dynamic Queries Using Dynamic Apex

2
  • so, this is a slightly different method from the one by sfdcfox right? but the concept is the same. just separate each path? Commented Mar 25, 2021 at 14:43
  • @joacoiudica yes, the concept is the same. Commented Mar 25, 2021 at 17:32
1

You have to use getSObject to get the relationship.

for(Item__c item : items){
     columns.add(String.valueOf(item.getSObject('listing_type__r').get('name'));
  }
}

You must log in to answer this question.

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