2

I have the following piece of code to get the valuetype. Is it possible to do this with getSObjectType() instead of getGlobalDescribe() since this is a lot slower.

Apex

Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(jSONSObject);
Schema.SObjectType targetType = Schema.getGlobalDescribe().get(sObjectApiName);
SObject newSobject = targetType.newSObject();
Map<String, Schema.sObjectField> targetFields = targetType.getDescribe().fields.getMap();
for (String key : fieldMap.keySet())
{
    Object value = fieldMap.get(key);
    Schema.DisplayType valueType = targetFields.get(key).getDescribe().getType();
    if (value instanceof String && valueType != Schema.DisplayType.String)
    {
        String svalue = (String)value;
        if (valueType == Schema.DisplayType.Date)
            newSobject.put(key, Date.valueOf(svalue));
        else if(valueType == Schema.DisplayType.DateTime)
            newSobject.put(key, DateTime.valueOfGmt(svalue));
        else if (valueType == Schema.DisplayType.Percent || valueType == Schema.DisplayType.Currency)
            newSobject.put(key, svalue == '' ? null : Decimal.valueOf(svalue));
        else if (valueType == Schema.DisplayType.Double)
            newSobject.put(key, svalue == '' ? null : Double.valueOf(svalue));
        else if (valueType == Schema.DisplayType.Integer)
            newSobject.put(key, Integer.valueOf(svalue));
        else if (valueType == Schema.DisplayType.Base64)
            newSobject.put(key, Blob.valueOf(svalue));
        else
            newSobject.put(key, svalue);
    }
    else
        newSobject.put(key, value);
}
insert newSobject;
1

1 Answer 1

3

If you already have the name, Type.forName can do this. Also, you can use the new(ish) switch statement for better legibility:

String jSONSObject = '{}';
String sObjectApiName = 'Account';
Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(jSONSObject);
SObject newSobject = (sObject)Type.forName('Schema',sObjectApiName).newInstance();
Map<String, Schema.sObjectField> targetFields = newSobject.getSObjectType().getDescribe().fields.getMap();
for (String key : fieldMap.keySet()) {
    Object value = fieldMap.get(key);
    value = value == ''? null: value;
    switch on targetFields.get(key)?.getDescribe().getType() {
        when DATE {
            value = Date.valueOf((String)value);
        }
        when DATETIME {
            value = DateTime.valueOf((String)value);
        }
        when PERCENT, CURRENCY {
            value = (Decimal)value;
        }
        when DOUBLE {
            value = Double.valueOf(value);
        }
        when INTEGER {
            value = (Integer)value;
        }
        when BASE64 {
            value = Blob.valueOf((String)value);
        }
    }
    newSobject.put(key, value);
}
insert newSobject;
3
  • Thanks for the answer. I get a nullpointer exception on: switch on targetFields.get(key).getDescribe().getType() {. The annotationdoes not seem to be correct for value = Decimal.valueOf(value); and value = Blob.valueOf(value);. Could you elaborate please
    – Thomas
    Commented Jan 19, 2021 at 18:04
  • @Thomas I had "translated" from your original code. I've cleaned this up so that it should compile and even fixed the null pointer issue, which was likely because of a misspelled field name.
    – sfdcfox
    Commented Jan 19, 2021 at 19:28
  • Thanks, your the greatest!
    – Thomas
    Commented Jan 20, 2021 at 20:31

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