0

The goal is to get base64 of attachments of each record to render them in a visualforce page. Each record may have any number of attachments or no attachments at all.

Map<Id, SObject> results = new Map<Id, SObject>([
    SELECT  Id, 
    Name, 
    URL__c FROM 
    MyCustomeObj__c
    WHERE 
    Id = 'my id'
    ]);

I am trying to add a new field with a value like this:

Map<Id, List<ContentDocumentLink>> attIdMap = new Map<Id, List<ContentDocumentLink>>();
vIds = results.keySet();
    for (Id i : vIds) {
        attIdMap.put(i, [SELECT LinkedEntityId, ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId = :i]);
    }
    //System.debug(attIdMap);

    Map<Id, List<ContentVersion>> bodyMap = new Map<Id, List<ContentVersion>>();
    for (Id key : attIdMap.keySet()) {
        List<ContentDocumentLink> temp = attIdMap.get(key);
        List<ContentVersion> cv = new List<ContentVersion>();
        if (temp.size() == 0) {
            bodyMap.put(key, null);
        } else {
            for (Integer j = 0; j < temp.size(); j++) {
                Id contDocId = (Id) temp[j].get('ContentDocumentId');
                cv.add([SELECT VersionData FROM ContentVersion WHERE ContentDocumentId = :contDocId]);
            }
            bodyMap.put(key, cv);
        }
    }
    //System.debug(bodyMap);

    List<SObject> sendThis = new List<SObject>();
    for (Id key : bodyMap.keySet()) {
        List<SObject> temp = bodyMap.get(key);
        List<String> realBodyList = new List<String>();
        SObject temp2;
        if (bodyMap.get(key) == null) {
            sendThis.add(results.get(key));
        } else {
            for (Integer k = 0; k < temp.size(); k++) {

                realBodyList.add( (String) EncodingUtil.base64Encode((Blob) temp[k].get('VersionData')));
            }
            temp2 = results.get(key);
            temp2.put('bodyList', realBodyList);
        }
        sendThis.add(temp2);
    }

    System.debug(sendThis);

Even though this is compiling successfully, executing is getting failed. It is giving me the following error:

ERROR: System.SObjectException: Invalid field bodyList for MyCustomeObj__c

As you can see both the custom object and temp2 are SObject types. I am getting custom object into temp2 and then trying to add 'bodyList' field to temp2. What's wrong with this? And how can I add a new field to the already existing object?

  • What is stored in realBodyList what does this list represent? – Oleksandr Berehovskyi Jan 25 at 7:47
  • I am storing contentversion in realbodylist. realBodyList.add( (String) EncodingUtil.base64Encode((Blob) temp[k].get('VersionData'))); – Illusion Jan 25 at 7:49
  • and to what field on your Sobject to you want to add List of contentversions ? temp2.put('bodyList', realBodyList); - here first param should be API name of Sobject field, second value for that field. – Oleksandr Berehovskyi Jan 25 at 7:51
  • There's no field on sobject. I want to create a new field and add realbodylist to that field. – Illusion Jan 25 at 7:53
  • you are not allowed to create new fields in such way in apex. you can only do it by means of Metadata API. What type should be of new field ? Any way you are not allowed to store blob (base64) in custom field. Why do you want to store Blob in custom field. Looks like it is XY problem – Oleksandr Berehovskyi Jan 25 at 7:57
3

In order to have something additional related to each SObject record with purpose to show it on VF page, you want to have wrapper class. This class will store sobject record itself and related to it body list.

Wrapper example:

public class CustomObjWrapper{
    public MyCustomeObj__c sobj {get; set;}
    public List<String> bodyList {get; set;}

    public CustomObjWrapper(MyCustomeObj__c sobj){
        this.sobj = sobj;
        bodyList = new List<String>();
    }
}

after that in results Map you want to store wrappers:

Map<Id, CustomObjWrapper> results = new Map<Id, CustomObjWrapper>();
for(SObject sobj :[
    SELECT  Id, 
    Name, 
    URL__c FROM 
    MyCustomeObj__c
    WHERE 
    Id = 'my id'
    ]){

    results.put((Id) sobj.get('Id'), new CustomObjWrapper(sobj));
}

and now here you can add value for wrapper's field:

CustomObjWrapper temp2 = results.get(key);
...
temp2.bodyList = realBodyList;
  • I am getting the error Constructor not defined: "[CustomObjWrapper].<Constructor>(SObject)". I have a created a new class with the name CustomObjWrapper. What am I doing wrong here? – Illusion Jan 26 at 22:29
  • 1
    Never mind. Figured it out! I have to cast the sobj as custom object like this: results.put((Id) sobj.get('Id'), new CustomObjWrapper((MyCustomObj__c) sobj)); – Illusion Jan 26 at 22:59

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.