I have an Aura component and I want to iterate through a wrapper class of objects, which has two lists as properties. While I can iterate through the wrapper class list, my lists come up as null when I try to iterate through them. My unit tests show me it's not an Apex issue--the lists are filled. But something is stopping my lists from showing as filled when I try to iterate through them. Am I missing something about how my lists need to be set? Or am I missing an Aura visibility wrinkle?
Wrapper class:
public with sharing class projectProgress {
@AuraEnabled public integer riskCount {get;set;} //count of risks related to project
@AuraEnabled public integer riskProgress {get;set;} //value for risk progress bar
@AuraEnabled public integer issueCount {get;set;} //count of issues related to project
@AuraEnabled public string projectstage {get;set;} //value for project stage
@AuraEnabled public string cardTitle {get;set;} //value for project stage
@auraEnabled public PSE__Proj__c project{get;set;} //current project record
@auraEnabled public List<PSE__Risk__c> riskList{get;set;} //current Risks
@auraEnabled public List<PSE__Issue__c> issueList{get;set;} //current Issues
public projectProgress() {
riskList = new List<pse__Risk__c>();
issueList = new List<pse__Issue__c>();
}
}
My Apex controller for the component generates a list of projectProgress objects from an initial SOQL of the project object, and then adds lists of related risks and issues.
public with sharing class progressPageController {
@AuraEnabled
public static List<projectProgress> initClass(){
List<projectProgress> projectProgresses = new List<projectProgress>();
//get projects
Map<ID, pse__proj__c> projectsMap = new Map<ID, pse__proj__c>([SELECT Id, Name, ... FROM PSE__Proj__c WHERE ... ORDER BY ...]);
//get risks
List<pse__Risk__c> risks = [SELECT Id, pse__Project__c, Name ... FROM pse__Risk__c WHERE pse__Project__c IN :projectsMap.keySet()];
//map for holding risks by project id
Map<Id,List<pse__Risk__c>> riskMap = new Map<Id,List<pse__Risk__c>>();
//loop through and add to map
for(pse__Risk__c thisRisk : risks){
if(riskMap.get(thisRisk.pse__Project__c)==null){
List<pse__Risk__c> thisRiskList = new List<pse__Risk__c>();
thisRiskList.add(thisRisk);
riskMap.put(thisRisk.pse__Project__c,thisRiskList);
} else {
riskMap.get(thisRisk.pse__Project__c).add(thisRisk);
}
}
//get issues
List<pse__Issue__c> issues = [SELECT Id, pse__Project__c, Name FROM PSE__Issue__c WHERE pse__Project__c IN :projectsMap.keySet()];
//map for holding issues by project id
Map<Id,List<pse__Issue__c>> issueMap = new Map<Id,List<pse__Issue__c>>();
//loop through and add to map
for(pse__Issue__c thisIssue : issues){
if(issueMap.get(thisIssue.pse__Project__c)==null){
List<pse__Issue__c> thisIssueList = new List<pse__Issue__c>();
thisIssueList.add(thisIssue);
IssueMap.put(thisIssue.pse__Project__c,thisIssueList);
} else {
issueMap.get(thisIssue.pse__Project__c).add(thisIssue);
}
}
//loop through all projects creating projectProgress objects
for(pse__proj__c thisProject : projectsMap.values()){
projectProgress obj = new projectProgress();
obj.project = thisProject;
//set stage for everything but In Progress
if(thisProject.pse__Stage__c <> 'In Progress'){
obj.projectstage = thisProject.pse__Stage__c;
}
//add risks from the map
if(riskMap.get(thisProject.Id)!=null){
obj.riskList = riskMap.get(thisProject.Id);
obj.riskCount = obj.riskList.size();
} else {
obj.riskCount = 0;
}
//add issues from the map
if(issueMap.get(thisProject.Id)!=null){
obj.issueList = issueMap.get(thisProject.Id);
obj.issueCount = obj.issueList.size();
} else {
obj.issueCount = 0;
}
obj.cardTitle = thisProject.Name;
projectProgresses.add(obj);
}
return projectProgresses;
}
}
My JS controller is very simple, it just loads up a list of objects
({
doInit : function(component, event, helper) {
//call apex class method
var action = component.get('c.initClass');
action.setCallback(this,function(response){
component.set('v.myProjectProgressList', response.getReturnValue());
});
$A.enqueueAction(action);
}
})
My component iterates through the wrapper class and everything works great except the lists, which are empty, even though my apex unit tests show them as having objects in them. So I think it's a visibility issue.
<aura:component controller="progressPageController" implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="myProjectProgressList" type="List"/>
<aura:iteration items="{!v.myProjectProgressList}" var="projectProgress">
{!projectProgress.project.Name} //works fine
<ul>
<aura:iteration items="{!projectProgress.issueList}" var="issue">
<li>{!issue.Name}</li> //is null, doesn't show
</aura:iteration>
</ul>
</aura:iteration>
</aura:component>
console.log(JSON.stringify(response.getReturnValue()));
to see if you recieve result from apex?