function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ethan HotzEthan Hotz 

Rendering a table with data from a nested map within a wrapper class

I'm trying to render a table using values from a list of a wrapper class, which contains a Map<String, Map<Date, Integer>> for each instance.

The VF:
<apex:pageBlock >
        
        <apex:commandButton action="{!displayData}" Value="Display Data" reRender="tableBlock"/>
    </apex:pageBlock>
    <apex:pageBlock id="tableBlock">
    
        <apex:pageBlockTable value="{!dummyList}" var="dummyVar" >
          
            <apex:column headerValue="Developer">
                
            </apex:column>
            <apex:repeat var="week" value="{!formattedWeekList}">
            <apex:column headerValue="{!week}">
                
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        <apex:repeat var="dev" value="{!userList}">
        <apex:pageBlockTable value="{!dev.projectMap}" var="project" id="userTable" rendered="{!tableVisible}">
            <apex:column headerValue="{!dev.userName.name}">
                <apex:outputText >{!project}</apex:outputText>
            </apex:column>
            <apex:repeat value="{!dev.projectMap[project]}" var="date"> <!-- This is ID'd as the cause of the null map key -->
            <apex:column headerValue="0" > <!-- Placeholder value   -->
                 {!dev.projectMap[project][date]}
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        </apex:repeat>
        
    </apex:pageBlock>

And the relevant part of the controller. This method is called for each wrapper class instance whenever I press the Display Data button:
public void checkData() {
            projectMap = new Map<String, Map<Date,Integer>>();
            Set<WeeklyProjectStats__c> querySet = new Set<WeeklyProjectStats__c>();
            Map<ID, Set<WeeklyProjectStats__c>> queryMap = new Map<ID, Set<WeeklyProjectStats__c>>();
            
            for (WeeklyProjectStats__c item : projectList) { //Create new list, if caseid != this.case, add
                querySet.add(item);
                if (querymap.containsKey(item.Case__c)) { 
                    Set<WeeklyProjectStats__c> innerset = queryMap.get(item.Case__c);
                    innerset.add(item);
                    queryMap.put(item.Case__c, innerset);
                } else {
                    Set<WeeklyProjectStats__c> tset = new Set<WeeklyProjectStats__c>();
                    tset.add(item);
                    queryMap.put(item.Case__c, tset);
                }
               
            }
//if (!queryMap.containsKey(TeamAllocationController.caseID)) queryMap.put(TeamAllocationController.caseID, null);
            
            
            if (queryMap.isEmpty()) {
                Map<Date,Integer> tMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    tmap.put(week, 1);
                }
                projectMap.put('No projects assigned to this user.', tMap);
                return;
            }
            
            for (ID project : queryMap.keySet()) {
                Map<Date,Integer> innerMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    
                    Integer hours;
                    WeeklyProjectStats__c tempStats = getListItem(querySet, project, week);
                    if (tempStats == null) {
                        hours = 0;
                    } else {
                        Set<WeeklyProjectStats__c> tset = queryMap.get(project);
                        WeeklyProjectStats__c tStat = getListItem(tset, project, week);
                        hours = (Integer)tStat.AssignedHours__c;
                    }
                    
                    innermap.put(week, hours);
                    
                }
                
                projectMap.put(project, innerMap);
            }
            
        }
        
        public WeeklyProjectStats__c getListItem(Set<WeeklyProjectStats__c> statList, ID project, Date week) {
            for (WeeklyProjectStats__c item : statList) {
                if (item.Case__c == project && item.Week__c == week) return item;
            }
            return null;
        }

As is, the page returns a map key null not found error. The weird thing is, whenever I enable the 
if (!queryMap.containsKey(TeamAllocationController.caseID)){ queryMap.put(TeamAllocationController.caseID, null); }

line, the table renders fine, except with null keys instead of the current page's case ID. I've probed most of my code with debug logs showing that the map seems to be populated as it should, so I have no idea what could be causing the page to fail.
 
Andrew EchevarriaAndrew Echevarria
Could you post some more of the apex? Try removing the "dev." from the PageBlockTable Value parameter.
Ethan HotzEthan Hotz
The dev variable references the specific user from the userlist, so I can't remove that or the page won't know where to find the project map. Here's the entire controller:
 
public class TeamAllocationController {
    public String managerName = 'Manager name';
    public List<Integer> dummyList {get;set;}
    

    public static Case caseInstance {get; set;}
    public static ID caseID {get; set;}
    public static List<WeeklyProjectStats__c> insertList {get;set;}
    public Map<String, String> sizingMap {get;set;}
    
    public String selectedTeam {get; set;}
    public List<SelectOption> teamList {get; set;}
    
    public static List<Date> weekList {get {return CalendarClass.getInstance().getNextMondays(8);} set;}
    public List<String> formattedWeekList {get { return formatWeekList();} set;}
    
    public List<WeeklyProjectStats__c> userProjects {get;set;}
    public List<UserWrapperClass> userList {get;set;}
    public UserWrapperClass selectedUser {get;set;}
    public Date selectedWeek {get; set;}
    public String selectedProject {get;set;}
    public boolean tableVisible {get;set;}
    

    public TeamAllocationController(ApexPages.StandardController controller) {
        dummyList = new List<Integer>();
        insertList = new List<WeeklyProjectStats__c>();
        tableVisible = false;
        getData();
        setUserList();
    }
    

    public void getData() {
        caseID = ApexPages.currentPage().getParameters().get('id');
        try {
            caseInstance = [SELECT Case.SFDC_Sizing__c, Case.SIS_Sizing__c, Case.SRS_Sizing__c, Case.DB_Sizing__c,
            Case.DocuSign_Sizing__c, Case.Integration_Sizing__c, Case.Admin_Sizing__c FROM Case WHERE ID = :caseID LIMIT 1];
            
        } catch(Exception e) {
            System.debug(e);
        }
    
        teamList = new List<SelectOption>();
        sizingMap = new Map<String, String>();
        List<SObjectField> fieldlist = new List<SObjectField> {Case.SFDC_Sizing__c, Case.SIS_Sizing__c, Case.SRS_Sizing__c, Case.DB_Sizing__c,
        Case.DocuSign_Sizing__c, Case.Integration_Sizing__c, Case.Admin_Sizing__c};
        for (SObjectField field : fieldlist) {
            if (caseInstance.get(field) != null && Integer.valueOf(caseInstance.get(field)) > 0) {
                String s = String.valueOf(field.getDescribe().getLabel());
                teamList.add(new SelectOption(s, s));
                sizingMap.put(s, String.valueOf(caseInstance.get(field)));
                
            }
        }
        selectedTeam = String.valueOf(teamList[0]);
    }
    
    public List<Date> getDateList() { return weekList; }
    public List<UserWrapperClass> getUserList() { return userList; }
   
    public List<String> formatWeekList() {
        List<String> tempList = new List<String>();
        for (Date day: weekList) {
            tempList.add(day.format());
        }
        return tempList;
    }
    
    public PageReference saveData() {
        //Upsert changed data
        return null;
    }
    
    
    public PageReference displayData() {
        
        for (UserWrapperClass u : userList) {u.checkData(); }
        tableVisible = true;
        return null;
    }
    
    public PageReference changeTeam() {
        
        return null;
    }
    
    public void setUserList() {
        userList = new List<UserWrapperClass>();
        for (List<User> uList : [SELECT Name FROM User WHERE Manager_Name__c = :managerName AND isActive = True]) {   //WHERE user is in team?
            for (User u : uList) {
                
                userList.add(new UserWrapperClass(u));
            }
        }
        
    }
    
    
    public class UserWrapperClass {
        public User userName {get;set;}
        public List<WeeklyProjectStats__c> projectList {get;set;}
        public Map<String, Map<Date, Integer>> projectMap {get;set;}
        public Map<Date, String> hourMap {get;set;}
        
        public UserWrapperClass(User u) {
            userName = u;
            projectList = new List<WeeklyProjectStats__c>();
            hourMap = new Map<Date, String>();
            setMaps();
            
        }
        
        public void setMaps() {
            Date thisMonday = CalendarClass.getInstance().getMonday();
            for (List<WeeklyProjectStats__c> projList : 
            [SELECT Case__c, AssignedHours__c, Week__c FROM WeeklyProjectStats__c WHERE User__c = :userName.id AND Week__c >= :thisMonday]) { //Where is not this case
                for (WeeklyProjectStats__c proj : projList) {
                    projectList.add(proj);
                }
            }
        }
        
        
        public void checkData() {
            projectMap = new Map<String, Map<Date,Integer>>();
            Set<WeeklyProjectStats__c> querySet = new Set<WeeklyProjectStats__c>();
            Map<ID, Set<WeeklyProjectStats__c>> queryMap = new Map<ID, Set<WeeklyProjectStats__c>>();
            
            for (WeeklyProjectStats__c item : projectList) {
                querySet.add(item);
                if (querymap.containsKey(item.Case__c)) { 
                    Set<WeeklyProjectStats__c> innerset = queryMap.get(item.Case__c);
                    innerset.add(item);
                    queryMap.put(item.Case__c, innerset);
                } else {
                    Set<WeeklyProjectStats__c> tset = new Set<WeeklyProjectStats__c>();
                    tset.add(item);
                    queryMap.put(item.Case__c, tset);
                }
               
            }
            //if (!queryMap.containsKey(TeamAllocationController.caseID)) queryMap.put(TeamAllocationController.caseID, null); {1}
            //If above line enabled, table is rendered 
            
            if (queryMap.isEmpty()) {
                Map<Date,Integer> tMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    tmap.put(week, 1);
                }
                projectMap.put('No projects assigned to this user.', tMap); {2}
                
                return;
            }
            
            for (ID project : queryMap.keySet()) {
                Map<Date,Integer> innerMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    
                    Integer hours;
                    WeeklyProjectStats__c tempStats = getListItem(querySet, project, week);
                    if (tempStats == null) {
                        hours = 0;
                    } else {
                        Set<WeeklyProjectStats__c> tset = queryMap.get(project);
                        WeeklyProjectStats__c tStat = getListItem(tset, project, week);
                        hours = (Integer)tStat.AssignedHours__c;
                    }
                    
                    innermap.put(week, hours);
                    
                }
                
                projectMap.put(project, innerMap);
            }
            
        }
        
        public WeeklyProjectStats__c getListItem(Set<WeeklyProjectStats__c> statList, ID project, Date week) {
            for (WeeklyProjectStats__c item : statList) {
                if (item.Case__c == project && item.Week__c == week) return item;
            }
            return null;
        }
        
    
    }
    
}

I guess the crux of the issue seems to be: why is the table rendered when a key is manually added on one line(at {1}), but not rendered when I do so on another line(at {2})?