0

I am trying to deserialize a json string and get the fieldtypes but get an error on the valueType. I am trying to simulate a Json request from postman to send a Post with a list of accounts.

I dont know if my JSON is correct from postman see:

enter image description here

  1. Is my JSON correct?
  2. Why does this result in an NullPointerException?

Apex

   Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(requestString);
    system.debug('[UploadDocuments]fieldMap: ' + fieldMap); 
    
    SObjectType sobjType = ((SObject)(Type.forName('Schema.' + 'Account').newInstance())).getSObjectType();
    SObject newSobject = sobjType.newSObject();

    Map<String, Schema.sObjectField> targetFields = sobjType.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;
    system.debug('newSobject: ' + newSobject); 

Debug of fieldmap: {Accts=({name=Alice, title=title1}, {name=Ben, title=title2})}

This issue is related to: How to dynamically get name of object JSON String

Thanks in advance.

2
  • Can you give the line of the NPE ?
    – Badbaxx
    Jan 19, 2021 at 10:33
  • @Badbaxx Its the valueType line see: Schema.DisplayType valueType = targetFields.get(key).getDescribe().getType();
    – Thomas
    Jan 19, 2021 at 10:41

1 Answer 1

2

You're missing the part where you get "Accts" and operate on that resource.

Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(requestString);

Should start off as:

Map<String, Object> topLevelResource = (Map<String, Object>)JSON.deserializeUntyped(requestString);
List<Object> acctsList = (List<Object>)topLevelResource.get('Accts');
Account[] accountsToInsert = new Account[0];
for(Object acctItem: acctsList) {
  Map<String, Object> fieldMap = (Map<String, Object>)acctItem;
  Account thisAccount = new Account(); // Or dynamic, as in your code
  // put fields into thisAccount, and then...
  accountsToInsert.put(thisAccount);
}
insert accountsToInsert; // DML outside of loop is good
6
  • Thanks for your answer. Suppose I dont know Accts beforehand is there a way to extract this from the JSON dynamically?
    – Thomas
    Jan 19, 2021 at 10:43
  • @Thomas Then it's nested loop time: Map<String, Object> topLevelResource = (Map<String, Object>)JSON.deserializeUntyped(requestString); for(String topLevelKey: topLevelResource.keySet()) { List<Object> topLevelRecordList = (List<Object>)topLevelResource.get(topLevelKey); for(Object recordResource: topLevelRecordList) { Map<String, Object> fieldMap = (Map<String, Object>)recordResource; ...
    – sfdcfox
    Jan 19, 2021 at 10:47
  • Thanks. In this way get the map but what I meant is to get the Acct key itself dynamically as a string.
    – Thomas
    Jan 19, 2021 at 11:20
  • @Thomas the topLevelKey in this second example is the key. You could get just the keySet and convert it to a list if you prefer.
    – sfdcfox
    Jan 19, 2021 at 11:25
  • @Thomas nice to see you raising new questions for different issues even though they are related to one over-all solution. It might be nice to add links in subsequent questions back to the originating question as a sort of foot note (at the end of the question)...?
    – Phil W
    Jan 19, 2021 at 11:36

You must log in to answer this question.

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