7

I have a relatively large Map<String, String> which is basically a key/value map of sobject field names and their values. Obviously, all the values are strings, but fields are not (there are currencies, dates and so on). I need a simple way to be able to assign them all without having to make a check on each field individually.

I can't use simple

sobject.put(fieldname, value);

because there is type mismatch on most lines.

What I did think of is to use JSON deserialize, because then casting gets done implicitly (I think - it seems to work). So the idea would be to either compile a valid JSON string manually or maybe make a dummy object that has all the fields named the same, but of type String. Then I could just do

objectInstance.put(fieldname, value);
String jsonSerialized = JSON.serialize(objectInstance);
SObject sobj = (SObject)JSON.deserialize(jsonSerialized, SObject.class);

However, this firstly seems as a hassle and secondly it seems complicated and as if there's a simpler solution.

Can you offer another approach?

  • very interesting question ! I always end up using describe calls to determine the data types. I wonder if someone has a better solution – ManSpan Nov 14 '13 at 8:51
6

The key to this is to use the Apex Describe functionality against your object and key names (your field names) in your map. This will give you the type information you need via DescribeFieldResult, to call the appropriate string conversion methods depending on the value of the SOAPType. Something like this should get you started...

    Map<String, String> valuesByFieldName = new Map<String, String>
        {
            'Name' => 'Record Name',
            'Date__c' => '2013-11-14',
            'MyCheckbox__c' => 'True',
            'Text__c' => 'Some Text'
        };
    Map<String, SObjectField> fieldMap = Test__c.sObjectType.getDescribe().fields.getMap();
    Test__c newRecord = new Test__c();
    for(String fieldName : valuesByFieldName.keySet())
    {
        SObjectField fieldToken = fieldMap.get(fieldName);
        DescribeFieldResult fieldDescribe = fieldToken.getDescribe();
        String fieldStringValue = valuesByFieldName.get(fieldName);
        Object fieldValue = null;
        if(fieldDescribe.getSOAPType() == Schema.SoapType.Date)
            fieldValue = Date.valueOf(fieldStringValue);
        else if(fieldDescribe.getSOAPType() == Schema.SoapType.DateTime)
            fieldValue = DateTime.valueOf(fieldStringValue);
        else if(fieldDescribe.getSOAPType() == Schema.SoapType.Boolean)
            fieldValue = Boolean.valueOf(fieldStringValue);
        else if(fieldDescribe.getSOAPType() == Schema.SoapType.String)
            fieldValue = fieldStringValue;
        if(fieldValue!=null)
            newRecord.put(fieldName, fieldValue);
    }

NOTE: You can try to use JSON serialisation, but unless your giving it at some point the strict type information (e.g. your object) its going to really only try its best to infer the data types from the values. The above code is more explicit and gives you more control over custom type conversions should you need it.

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.