0

I am needing a little advice on a issue I'm facing right now on a Heap Size Error when getting a list of files into a Data table.

''JSON string exceeds heap size limit''

I have a custom component that we can upload files and display them in a table and delete download etc...

After Uploading a couple of PDF's I noticed all the files disappeared (But they were still attached to the file in the related section)

I've read a lot on this in the last day or two because its really messing me around. I gather that we can only have around 6mb per String.

Is there any way to combat this or is the best way just to use salesforce standard functionality and use the related files section.

 @AuraEnabled
    public static String getContentDetails(String recordId) {
        
        
        // Get Content documentID from ContentDocumentLink by propertyListingID
        List<ContentDocumentLink> contentDocumentList = new List<ContentDocumentLink>();
        if (ContentDocumentLink.SObjectType.getDescribe().isAccessible() &&
            Schema.SObjectType.ContentDocumentLink.fields.ContentDocumentId.isAccessible()
        ) {
            contentDocumentList =   [SELECT ContentDocumentId, 
                                        LinkedEntityId 
                                    FROM ContentDocumentLink 
                                    WHERE LinkedEntityId =: recordId LIMIT 50];

        }
        Set<Id> contentDocumentId = new Set<Id>();
        Set<String> fileExt = new Set<String>{'png','jpg','jpeg'};  
        List<ContentVersion> contentVersionList = new List<ContentVersion>();
        
        for (ContentDocumentLink link : contentDocumentList) {
            contentDocumentId.add(link.ContentDocumentId);
        }
            
        Id profileId = userinfo.getProfileId();
        String profileName = [SELECT Id,
                                     Name 
                              FROM Profile 
                              WHERE Id = :profileId
                            ].Name;

        if (profileName.equalsIgnoreCase(System.label.Customer_User_Profile) &&
            ContentVersion.SObjectType.getDescribe().isAccessible()
        ) {
            contentVersionList = [SELECT Id, 
                                         VersionData, 
                                         FileType, 
                                         Title, 
                                         FileExtension,
                                         ContentDocument.CreatedBy.Name, 
                                         ContentDocument.ContentSize,
                                         CreatedDate, 
                                         ContentDocumentId, 
                                         ContentDocument.FileType,
                                         ContentDocument.SharingPrivacy, 
                                         ContentDocument.PublishStatus,
                                         ContentDocument.Description
                                FROM   ContentVersion 
                                WHERE  ContentDocumentId IN : contentDocumentId
                                AND FileExtension != :fileExt
                                AND ContentDocument.SharingPrivacy = 'N' 
                                ];
        } else if (ContentVersion.SObjectType.getDescribe().isAccessible()) {
            contentVersionList = [SELECT Id, 
                                         VersionData, 
                                         FileType, 
                                         Title, 
                                         FileExtension,
                                         ContentDocument.CreatedBy.Name, 
                                         ContentDocument.ContentSize,
                                         CreatedDate, 
                                         ContentDocumentId, 
                                         ContentDocument.FileType,
                                         ContentDocument.SharingPrivacy, 
                                         ContentDocument.PublishStatus,
                                         ContentDocument.Description 
                                  FROM   ContentVersion 
                                  WHERE  ContentDocumentId IN : contentDocumentId
                                  AND FileExtension != :fileExt ORDER BY CreatedDate DESC
                                ];
                                System.debug(Limits.getHeapSize());
        } //End of if-else
        return JSON.serialize(contentVersionList);
    
    }

Lwc :

  // To refresh the uploaded table & show the file details
  handleSync() {
    this.isLoading = true;
    getContentDetails({
      recordId : this.recordId,
    })
      .then((result) => {
        console.log('SYNC');
        this.dropdownValue();
        let parsedData = JSON.parse(result);
        let stringifiedData = JSON.stringify(parsedData);
        let finalData = JSON.parse(stringifiedData);
        
        finalData.forEach((file) => {          
          file.fileUrl =
            this.getBaseUrl() +
            "sfc/servlet.shepherd/version/renditionDownload?rendition=THUMB720BY480&versionId=" +
            file.Id;

            //2.0
            this.placeholder = "Select Document Type";
            this.docType = '';
          console.log('communityBasePath',file);
          console.log('file.fileUrl',file.fileUrl);
          console.log('communityUrl',this.communityUrl);
          console.log('this.usedInCommunity',this.usedInCommunity);
          console.log('location.host',location.host);
          console.log(file.ContentDocument.Description);
          file.CREATED_BY = file.ContentDocument.CreatedBy.Name;
          file.Size = this.formatBytes(file.ContentDocument.ContentSize, 2);
          file.Type = file.FileExtension;
          file.createdDate = file.CreatedDate;
          file.contentId = '/' + file.ContentDocumentId;
          file.Privacy = file.ContentDocument.SharingPrivacy;
          file.DocumentType = file.ContentDocument.Description;
          file.downloadUrl = this.getBaseUrl()+'sfc/servlet.shepherd/document/download/'+file.ContentDocumentId;
          if (file.Privacy == "N") {
            file.Privacy = "Public";
          } else {
            file.Privacy = "Private";
          }
        });
        this.dataList = finalData;
        this.selectedList = finalData
        console.log('FinalData: '+this.dataList)
      })
      .catch((error) => {
        console.log(error)
      })
      .finally(() => {
        this.isLoading = false;
      });
  }

With only a few small Files Uploaded:

enter image description here

After Either uploading many medium sized files or a big file:

enter image description here

The main reason for use of the table is

  • To search for documents if there are lots
  • Change privacy type for the file
  • and view the Document type / Change the Document type of the file.
1
  • I change the return type to a List instead of a String. Also Added navigate mixin' to take care of the download. Jan 31, 2023 at 9:26

2 Answers 2

2

To download or to delete a file you don't need its data, just its id, and looking at the posted JS code, it seems that you don't use VersionData, so you could just remove it from both SOQL.
Once you removed VersionData, the file size shouldn't be an issue anymore.
Moreover the apex method could simply return a List<ContentVersion> instead of returning a String, this way you don't have to serialize it in apex and parse it in JS and in getContentDetails.then() you could loop over result.

1

This limit you can't avoid, even if the heap size is 6MB in my experience I could handle files upto 4.5MB only in past with Apex.

As @RubenDG suggested you don't need the file Content to generate the Datatable, you need only the file Ids. Instead of fetching the files through Apex for download, use Navigation Mixin to redirect to standard file preview page and let User manually download the file from the standard preview page. as I have explained in this SFSE answer.

You must log in to answer this question.

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