2

I am in need of showing a list of records in a summarized format, say all records belonging to Type 1 are displayed first, followed by the records of Type 2, and so on.

Usually in visualforce page, the same is achieved using wrapper class. Now when I am doing the same in a lightning component, using the same approach of a wrapper class, I am finding it difficult to create an aura attribute of type wrapper class list. Can anyone please help?

What I have tried so far, is as follows :

Component's Js Controller init method :

 initRecords: function(component, event, helper) {
        // call the apex class method and fetch sub stage of loan appliction record 
        //alert('Modification in progress');
         var action = component.get("c.fetchSubStage");
         action.setParams({
                    'loanId': component.get("v.recordId")
                  });
             action.setCallback(this, function(response) {
              var state = response.getState();
                 //alert(state);
              if (state === "SUCCESS") {
                  var capturedResponse = response.getReturnValue();
                  console.log(JSON.stringify(capturedResponse));
               // set SubStage attribute with return value from server.
                  component.set("v.subStage", capturedResponse);

            }
        });
        $A.enqueueAction(action);

      // call the apex class method and fetch account list  
         var action = component.get("c.fetchDocuments");
//This method will return a list of wrapper class.
         action.setParams({
                    'loanId': component.get("v.recordId")
                  });
             action.setCallback(this, function(response) {
              var state = response.getState();
                 //alert(state);
              if (state === "SUCCESS") {
                  var storeResponse = response.getReturnValue();
                  console.log(JSON.stringify(storeResponse));
               // set AccountList list with return value from server.
                  component.set("v.DocList", storeResponse);
            }
        });
        $A.enqueueAction(action);
    },

Controller Apex Class :

public class DocumentListController {
    // method for fetching the Sub Stage of the Loan Application record.
    @AuraEnabled
    public static String fetchSubStage(Id loanId) {
        String subStage;
        List<Loan_Application__c> lstLoanApplication;
        if(String.isNotBlank(loanId)) {
            lstLoanApplication = [SELECT  ID, Sub_Stage__c FROM Loan_Application__c WHERE ID = :loanId LIMIT 1];
            if(!lstLoanApplication.isEmpty()) {
                subStage = lstLoanApplication[0].Sub_Stage__c;
            }
        }
        System.debug('Debug Log for subStage'+subStage);
        return subStage;
    }

    // method for fetch account records list  
    @AuraEnabled
    public static List <Document_Checklist__c> fetchDocuments(Id loanId) {
       //Map of Contact ID to Contact Name
       Map<String, List<Document_Checklist__c>> mapContactNametoDocChecklist = new Map<String, List<Document_Checklist__c>>();
       List < Document_Checklist__c > returnList = new List < Document_Checklist__c > ();
       List < Document_Checklist__c > lstOfDoc;
       List<DocumentListWrapper> lstDocumentWrapper = new List<DocumentListWrapper>();
       List<Loan_Application__c> lstLoanApplication = [SELECT  ID, Sub_Stage__c FROM Loan_Application__c WHERE ID = :loanId LIMIT 1];
       String subStage;
       String fieldsToQuery;

       if(!lstLoanApplication.isEmpty()) {
            subStage = lstLoanApplication[0].Sub_Stage__c;
       }
       System.debug('Debug Log for subStage'+subStage);

       if(subStage == 'Application Initiation') {
            fieldsToQuery = 'Id, Contact_Name__c, Document_Type__r.name, Document_Master__c, Document_Master__r.Name, Status__c, Original_Seen_and_Verified__c';
       }

       else if(subStage == 'File Check') {
            fieldsToQuery = 'Id, Contact_Name__c, Document_Type__r.name, Document_Master__c, Document_Master__r.Name, Status__c, File_Check_Completed__c';
       }

       else if(subStage == 'COPS:Data Maker') {
            fieldsToQuery = 'Id, Contact_Name__c, Document_Type__r.name, Document_Master__c, Document_Master__r.Name, Status__c, Document_Collection_Mode__c, Screened__c, Sampled__c';
       }

       else if(subStage == 'COPS:Data Checker') {
            fieldsToQuery = 'Id, Contact_Name__c, Document_Type__r.name, Document_Master__c, Document_Master__r.Name, Status__c, Document_Collection_Mode__c, Screened__c, Sampled__c';
       }

       else if(subStage == 'Scan: Data Maker') {
            fieldsToQuery = 'Id, Contact_Name__c, Document_Type__r.name, Document_Master__c, Document_Master__r.Name, Status__c, Scan_Check_Completed__c, Document_Collection_Mode__c, Screened__c, Sampled__c';
       }

       else if(subStage == 'Scan: Data Checker') {
            fieldsToQuery = 'Id, Contact_Name__c, Document_Type__r.name, Document_Master__c, Document_Master__r.Name, Status__c, Scan_Check_Completed__c, Document_Collection_Mode__c, Screened__c, Sampled__c';
       }

       System.debug('Debug Log for fieldsToQuery'+fieldsToQuery);
       if(String.isNotBlank(fieldsToQuery)) {
            String query = 'SELECT '+fieldsToQuery+' FROM Document_Checklist__c where Loan_Applications__c =\''+loanId+'\' ORDER BY Contact_Name__c NULLS FIRST';
            System.debug('Debug Log for query'+query);
            lstOfDoc = Database.query(query);
       }
       else {
            lstOfDoc = [select id,Contact_Name__c,Loan_Contact__r.name,Document_Type__r.name,Document_Master__c,Document_Master__r.name,Loan_Engine_Mandatory__c,Express_Queue_Mandatory__c,Status__c,Original_Seen_and_Verified__c,File_Check_Completed__c,Scan_Check_Completed__c from Document_Checklist__c where Loan_Applications__c =:loanId];
       }
       //lstOfDoc = [select id,Contact_Name__c,Loan_Contact__r.name,Document_Type__r.name,Document_Master__c,Document_Master__r.name,Loan_Engine_Mandatory__c,Express_Queue_Mandatory__c,Status__c,Original_Seen_and_Verified__c,File_Check_Completed__c,Scan_Check_Completed__c from Document_Checklist__c where Loan_Applications__c =:loanId];
        if(!lstOfDoc.isEmpty()) {
            for (Document_Checklist__c doc: lstOfDoc) {
                returnList.add(doc);
                System.debug('Debug Log for doc.Document_Type__r.name'+doc.Document_Type__r.name);
                System.debug('Debug Log for Document_Master__c'+doc.Document_Master__r.Name);
                if(!mapContactNametoDocChecklist.containsKey(doc.Contact_Name__c)) {
                    mapContactNametoDocChecklist.put(doc.Contact_Name__c,new List<Document_Checklist__c>());
                }
                mapContactNametoDocChecklist.get(doc.Contact_Name__c).add(doc);
            }
            for(String strContactName : mapContactNametoDocChecklist.keySet()) {
                lstDocumentWrapper.add(new DocumentListWrapper(strContactName, mapContactNametoDocChecklist.get(strContactName)));
            }
        } 
        System.debug('Debug Log for lstDocumentWrapper'+lstDocumentWrapper);   
        //For Testing Purpose 
        for(DocumentListWrapper objDocumentListWrapper : lstDocumentWrapper) {
            System.debug('Key:'+objDocumentListWrapper.strContactName);
            System.debug('Value:'+objDocumentListWrapper.lstDocumentCheckList);
        }
        return returnList;
        //return lstDocumentWrapper;
    }
    // method for fetch picklist values dynamic  
    @AuraEnabled
    public static List < String > getselectOptions(sObject objObject, string fld) {
        system.debug('objObject --->' + objObject);
        system.debug('fld --->' + fld);

        List < String > allOpts = new list < String > ();
        // Get the object type of the SObject.
        Schema.sObjectType objType = objObject.getSObjectType();

        // Describe the SObject using its object type.
        Schema.DescribeSObjectResult objDescribe = objType.getDescribe();

        // Get a map of fields for the SObject
        map < String, Schema.SObjectField > fieldMap = objDescribe.fields.getMap();

        // Get the list of picklist values for this field.
        list < Schema.PicklistEntry > values =
            fieldMap.get(fld).getDescribe().getPickListValues();

        // Add these values to the selectoption list.
        for (Schema.PicklistEntry a: values) {
            allOpts.add(a.getValue());
        }
        system.debug('allOpts ---->' + allOpts);
        allOpts.sort();
        return allOpts;
    }
     @AuraEnabled
        public static Id saveChunk(Id parentId, String fileName, String base64Data, String contentType, String fileId) {
            if (fileId == '') {
                fileId = saveTheFile(parentId, fileName, base64Data, contentType);
            } else {
                appendToFile(fileId, base64Data);
            }    
            system.debug('**'+fileId);
            return Id.valueOf(fileId);
        }
    public static Id saveTheFile(Id parentId, String fileName, String base64Data, String contentType) {
            base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
            Boolean isSuccess = false;
            Id returnId;
            /*
            Attachment oAttachment = new Attachment();
            oAttachment.parentId = parentId;

            oAttachment.Body = EncodingUtil.base64Decode(base64Data);
            oAttachment.Name = fileName;
            oAttachment.ContentType = contentType;
            system.debug('**insert'+oAttachment);
            insert oAttachment;
            */
            //New Logic to store the document in files. Added on 10 September, 2018
            ContentVersion conVer = new ContentVersion();
            conVer.ContentLocation = 'S'; // S specify this document is in SF, use E for external files
            conVer.PathOnClient = fileName; // The files name, extension is very important here which will help the file in preview.
            conVer.Title = fileName; // Display name of the files
            conVer.VersionData = (Blob)EncodingUtil.base64Decode(base64Data); // converting your binary string to Blog
            try {
                insert conVer;
                System.debug('Debug Log for inserted record ContentVersion'+conVer.Id);
            }
            catch(Exception exc) {
                System.debug('Debug Log for exception from ContentVersion'+exc);
            }
            if(String.isNotBlank(String.valueOf(conVer.Id))) {
                Id conDoc = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:conVer.Id].ContentDocumentId;
                //Create ContentDocumentLink
                ContentDocumentLink cDe = new ContentDocumentLink();
                cDe.ContentDocumentId = conDoc;
                cDe.LinkedEntityId = parentId; // you can use objectId,GroupId etc
                cDe.ShareType = 'I'; // Inferred permission, checkout description of ContentDocumentLink object for more details
                cDe.Visibility = 'InternalUsers';
                try {
                    insert cDe;
                    System.debug('Record Id:'+cDe.Id);
                }
                catch(Exception ex1) {
                    System.debug('Debug Log for exception from ContentDocumentLink'+ex1);
                }
                if(String.isNotBlank(String.valueOf(cDE.Id))) {
                    isSuccess = true;
                    returnId = cDE.Id;
                }

            }
            if(isSuccess) {
                Document_Checklist__c doc =[select Id,Status__c from Document_Checklist__c where Id=:parentId];
                doc.Status__c='Uploaded';
                update doc;
            }
            return returnId;
        }

        private static void appendToFile(Id fileId, String base64Data) {
            base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');

            Attachment a = [
                SELECT Id, Body
                FROM Attachment
                WHERE Id =: fileId
            ];

            String existingBody = EncodingUtil.base64Encode(a.Body);

            a.Body = EncodingUtil.base64Decode(existingBody + base64Data);

            update a;
        }

    @AuraEnabled
    public static list<Attachment> getAttachment(Id parentId)
    {
        return [SELECT ParentId, Name, Id, ContentType, BodyLength FROM Attachment where ParentId =: parentId];
    }

    @AuraEnabled
    public static List <Document_Checklist__c> saveLoan(List<Document_Checklist__c> listOfDoc) {
        system.debug('list-->'+listOfDoc);
        update listOfDoc;
        return listOfDoc;
    }

    @AuraEnabled
    public static List<ID> queryAttachments (Id propertyId) {
        List<ContentDocumentLink> links;
        List<ContentVersion> lstContentVersion;
        Set<Id> setContentVersionId = new Set<Id>();
        String objectAPIName = '';
        String keyPrefix = '';
        System.debug('Debug Log for propertyId'+propertyId);
        keyPrefix = String.valueOf(propertyId).substring(0,3);
        for( Schema.SObjectType obj : Schema.getGlobalDescribe().Values() ){
             String prefix = obj.getDescribe().getKeyPrefix();
              if(prefix == keyPrefix){
                        objectAPIName = obj.getDescribe().getName();
                        break;
               }
        }
        System.debug('Debug Log for objectAPIName:'+objectAPIName);
        if(String.isNotBlank(objectAPIName)) {
            if(objectAPIName == 'Document_Checklist__c') {
                links = [select id, LinkedEntityId, ContentDocumentId from ContentDocumentLink where LinkedEntityId=:propertyId];
                System.debug('Debug Log for links'+links.size());
                System.debug('Debug Log for links'+links);

                if (links.isEmpty()) {
                    return null;
                }

                Set<Id> contentIds = new Set<Id>();

                for (ContentDocumentLink link :links) {
                    contentIds.add(link.ContentDocumentId);
                }
                System.debug('Debug Log for contentIds'+contentIds);
                /*
                lstContentVersion = [SELECT Id, Title FROM ContentVersion WHERE ContentDocumentId IN :contentIds AND IsLatest=true];
                System.debug('Debug Log for lstContentVersion'+lstContentVersion);

                if(!lstContentVersion.isEmpty()) {
                    for(ContentVersion objContentVersion : lstContentVersion) {
                        setContentVersionId.add(objContentVersion.Id);
                    }
                }
                System.debug('Debug Log for setContentVersionId'+setContentVersionId);
                */
                List<Id> lstsettoList = new List<Id>(contentIds);            
                return lstsettoList;
            }

            else if(objectAPIName == 'Loan_Application__c') {
                List<Document_Checklist__c> lstDocumentList = [SELECT Id FROM Document_Checklist__c WHERE Loan_Applications__c =: propertyId];
                Set<Id> setDocumentListIds = new Set<Id>();
                System.debug('Debug Log for lstDocumentList'+lstDocumentList.size());
                if(!lstDocumentList.isEmpty()) {
                    for(Document_Checklist__c objDC : lstDocumentList) {
                        setDocumentListIds.add(objDC.Id);
                    }
                }
                System.debug('Debug Log for setDocumentListIds'+setDocumentListIds.size());
                if(!setDocumentListIds.isEmpty()) {
                    links = [select id, LinkedEntityId, ContentDocumentId from ContentDocumentLink where LinkedEntityId IN:setDocumentListIds];

                    if (links.isEmpty()) {
                        return null;
                    }

                    Set<Id> contentIds = new Set<Id>();

                    for (ContentDocumentLink link :links) {
                        contentIds.add(link.ContentDocumentId);
                    }
                    System.debug('Debug Log for contentIds'+contentIds);
                    List<Id> lstsettoList1 = new List<Id>(contentIds);            
                    return lstsettoList1;

                    //return [SELECT Id, Title FROM ContentVersion WHERE ContentDocumentId IN :contentIds AND IsLatest=true];
                }
            }

        }
        return new List<Id>();
    }

    public class DocumentListWrapper {
        @AuraEnabled String strContactName{get;set;}
        @AuraEnabled List<Document_Checklist__c> lstDocumentCheckList{get;set;}

        public DocumentListWrapper(String paramContactName, List<Document_Checklist__c> paramListDocChkLst) {
            this.strContactName = paramContactName;
            this.lstDocumentCheckList = paramListDocChkLst;
        }
    }
}

Below is the aura attribute which I want to change from a list of custom object, to a list of wrapper class, but that is not happening :

<aura:attribute name="DocList" type="Document_Checklist__c[]" description="store account records list"/>
3
  • Have you tried something and it hasn't worked? Can you share some code that would show what you've attempted thus far?
    – pchittum
    Sep 20, 2018 at 9:50
  • @pchittum, I have added what I have tried, above. Sep 20, 2018 at 13:17
  • 1
    @ShobhitSaxena - as provided in the answer, you cannot declare an aura:attribtue of type inner class. While it may work at instances, but its very well documented that its unsupported and that you should avoid it in all possible ways.
    – Jayant Das
    Sep 20, 2018 at 14:12

2 Answers 2

7

If I read this right, you want to use an inner class on aura:attribute tag. You cannot (rather should not) use an inner class as an aura attribute, instead you need to handle it differently. If that's what you are looking for, refer to the below excerpt from documentation:

Custom classes used for component attributes shouldn’t be inner classes or use inheritance. While these Apex language features might work in some situations, there are known issues, and their use is unsupported in all cases.

2
  • I was able to achieve the same. I am posting my final code here. Sep 22, 2018 at 10:39
  • It may work in scenario as mentioned in the documentation, but it’s also very clearly called out that it’s unsupported. You should try to avoid it as it cannot be guaranteed to work in every situation.
    – Jayant Das
    Sep 22, 2018 at 14:43
0

The aura attribute can be created as follows :

<aura:attribute name="WrapperClassList" type="ControllerClass.WrapperClass[]" description="store wrapper class records list"/>

I used it as follows :

<aura:attribute name="DocList1" type="DocumentListController.DocumentListWrapper[]" description="store wrapper class records list"/>

The controller class returns the list of wrapper and then it is manipulated in the component and js controller.

var action = component.get("c.fetchDocuments");
action.setParams({
        'loanId': component.get("v.recordId")
      });
 action.setCallback(this, function(response) {
  var state = response.getState();
     //alert(state);
  if (state === "SUCCESS") {
      var storeResponse = response.getReturnValue();
      console.log('List received'+storeResponse);
      console.log(JSON.stringify(storeResponse));
      component.set("v.DocList1", storeResponse);
}
});
$A.enqueueAction(action);

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