[SalesForce] getSObject – Dynamically Referencing Object Fields from Map

I have a Map of IDs of a custom object (scopeAccountMap).

I am iterating through each object in scopeAccountMap and I am creating a map of the fields for each of these objects.

I am receiving the following error:

Comparison arguments must be compatible types: SObject, String

I am receiving this error because scope[s].getSObject(fieldNameString) is returning an object. I understand this, but do not know the correct solution.

What do I need to do so that I am able to compare and set the field of scope[s].fieldNameString where fieldNameString could be Name, Id, etc. depending on the fields returned in the scope list.

Scope is a list of Custom_Object__c records.

The use case for this functionality is that if blank fields are returned from an endpoint which we are getting the data from, I do not want the retrieved field data to overwrite the existing fields if there is data in the existing fields.

  for(integer s=0; s < scope.size(); s++) {

  existingCustObj = [SELECT Id, Name from Custom_Object__c];

  Map<ID, Custom_Object__c> scopeAccountMap = new Map<ID, Custom_Object_c>(scope);

  system.debug(scopeAccountMap.keyset());

    for (ID idKey : scopeAccountMap.keyset()) {
        Custom_Object__c a = scopeAccountMap.get(idKey);
        Map<String, Object> fieldsToValue = a.getPopulatedFieldsAsMap();

    for (String fieldName : fieldsToValue.keySet()) {
        String fieldNameString = String.valueOf(fieldsToValue.get(fieldName));

        //BELOW IS WHERE I NEED TO DYNAMICALLY REFERENCE THE OBJECTS FIELDS********
        if (scope[s].getSObject(fieldNameString) == '' || scope[s].getSObject(fieldNameString) == null) {
        scope[s].getSObject(fieldNameString) = existingCustObj[0].getSObject(fieldNameString);    
        }

        else {
            system.debug('scope value is not blank');
        }

        System.debug('field name is ' + fieldName + ', value is ' + fieldsToValue.get(fieldName));
        }
    }

EDIT:

Upon modifying the code from .getSObject to .get I now receive the following error:

Expression cannot be assigned

This error is referencing the line where I assign scope[s] to existingCustObj[0].

Best Answer

getSobject() is the generic sObject method for obtaining an sObject instance value for a given relationship field name. Since you're simply mapping field values, what you need is get(), which returns the primitive value.

Here's an illustrative example to make the distinction a little clearer.

List<Contact> children = [SELECT Account.Name, Id, FirstName, LastName FROM Contact];

Id accountId = (Id)children[0].get('AccountId');
Account a = (Account)children[0].getSobject('Account');
String accountName = a.get('Name');
String fn = (String)children[0].get('FirstName');

Note that for the primitive values (String, and Id for a relationship field), we use get(). getSobject() is used when we want to work with an sObject instance for the relationship field in Apex, which you don't need here.