I am trying to dynamically deserialize a jsonstring (fieldmaplevels wil also be in custom metadata settings) but get the error:
Error: Invalid conversion from runtime type List to Map<String,ANY>
this is at line:
Map<String, Object> fieldMapLevel_0 = (Map<String, Object>)fieldMap.get('Accts');
I also tried:
Map<String, Object> fieldMapLevel_0 = new Map<String, Object>(fieldMap.get('Accts'));
But get : expected a Map with the same key and value types, or a valid SObject List
Apex
public with sharing class DynamicJSON{
public Map<String, Object> fieldMap;
public static void DynamicJSONmethod()
{
sObject newSobject;
List<sObject> sObjectList;
String jsonPayLoad = '{"Accts":[{"Name":"ABC","Exp":25,"Languages":[{"Name":"Apex","version": []},{"Name":"Java","versions":[{"version":1.8,"certification":true,"placeholder":{"target":"reached"}}]}]}]}';
Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(jsonPayLoad);
List<Data_Maps__mdt> mappings = [SELECT QualifiedApiName, label, Object__c , JSON_Object__c,sObjectApiNameLevel_0__c, sObjectApiNameLevel_1__c,sObjectApiNameLevel_2__c,sObjectApiNameLevel_3__c,
sObjectApiNameLevel_4__c FROM Data_Maps__mdt];
//level-0
if(mappings[0].sObjectApiNameLevel_0__c != null) {
sobject newSobjLevel_0 = (sObject)Type.forName('Schema',mappings[0].sObjectApiNameLevel_0__c).newInstance();//Account
Map<String, Object> fieldMapLevel_0 = (Map<String, Object>)fieldMap.get('Accts');
GetSobjectFields(newSobjLevel_0, fieldMapLevel_0);
//level-1
if(mappings[1].sObjectApiNameLevel_1__c != null) {
sobject newSobjLevel_1 = (sObject)Type.forName('Schema',mappings[1].sObjectApiNameLevel_1__c).newInstance();//Languages__c
Map<String, Object> fieldMapLevel_1 = (Map<String, Object>)fieldMap.get('Languages');
GetSobjectFields(newSobjLevel_1, fieldMapLevel_1);
//level-2
if(mappings[2].sObjectApiNameLevel_2__c != null) {
sobject newSobjLevel_2 = (sObject)Type.forName('Schema',mappings[0].sObjectApiNameLevel_2__c).newInstance();//versions__c
Map<String, Object> fieldMapLevel_2 = (Map<String, Object>)fieldMap.get('versions');
GetSobjectFields(newSobjLevel_2, fieldMapLevel_2);
//level-3
if(mappings[3].sObjectApiNameLevel_3__c != null) {
sobject newSobjLevel_3 = (sObject)Type.forName('Schema',mappings[0].sObjectApiNameLevel_3__c).newInstance();//placeholder__c
Map<String, Object> fieldMapLevel_3 = (Map<String, Object>)fieldMap.get('placeholder');
GetSobjectFields(newSobjLevel_3, fieldMapLevel_3);
//level-4
if(mappings[4].sObjectApiNameLevel_4__c != null) {
sobject newSobjLevel_4 = (sObject)Type.forName('Schema',mappings[4].sObjectApiNameLevel_4__c).newInstance();//target__c
Map<String, Object> fieldMapLevel_4 = (Map<String, Object>)fieldMap.get('target');
GetSobjectFields(newSobjLevel_4, fieldMapLevel_4);
}
}
}
}
}
}
public static sobject GetSobjectFields(sObject newSobj, Map<String,Object> fieldMap ){
Map<String,String> fieldsMap = new Map<String,String>();
Map<String, Schema.sObjectField> targetFields = newSobj.getSObjectType().getDescribe().fields.getMap();
system.debug('[UploadDocuments]targetFields: ' + targetFields);
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);
}
}
newSobj.put(fieldsMap.get(key), value);
}
insert newSobj;
system.debug('[DynamicJSON]newSobj: ' + newSobj);
return newSobj;
}
}
List<Object> fieldMapLevel_0 = fieldMap.get('Accts');
?Map<String, Object>
and JSON arrays intoList<Object>
. Since the JSON has 'Accts' as an array, this means you get a List and that is how you must process it.