2

Expecting Following Output:

[
    {
        "projectId": "fsdfdsfds",
        "projectName": "ProjectName",
        "totalRegularHours": "25",
        "totalOtherHours": "34"
    },
    {
        "projectId": "fsdfddsfds",
        "projectName": "ProjectName1",
        "totalRegularHours": "34",
        "totalOtherHours": "45"
    }
]

All the above data is in Same Custom Object Time_Sheet_Details__c, In this object we have date wise Time sheet Hours, I'm trying to Take the Summary of the Each Hours Type Based on Project.(Like above Response)

To get the totalRegularHours , I'm having one more List<AggregateResult> tsdtlBillRgr. After adding this when I ran the method from Anonymous Window, I'm getting this:

System.NullPointerException: Attempt to de-reference a null object

If we remove that AggregateResult of tsdtlBillRgr, then there is no Error. Can we have the Multiple AggregateResult in Single Apex Method. If Yes is this the right way to Implement,

@AuraEnabled(cacheable=true)
    public static List<ProjectHoursWrapper> projectHoursGraph(){
        List<ProjectHoursWrapper> tsdwrap = new List<ProjectHoursWrapper>();

        List<AggregateResult> tsdtlBillRgr = [SELECT Sum(Hours__c), Project__c, Project__r.name FROM Time_Sheet_Details__c 
                                              WHERE   Type_of_Hours__c ='Billable Regular' Group by Project__c, Project__r.name];

        Map<Id, List<AggregateResult>> tDetailsRegular= new Map<Id, List<AggregateResult>>();
        for(AggregateResult tDetailReg:tsdtlBillRgr){
            id key = (Id)(tDetailReg.get('Project__c'));
            tDetailsRegular.get((Id)(tDetailReg.get('Project__c'))).add(tDetailReg);
        } 

        List<AggregateResult> tsdtl =[SELECT Project__c, Project__r.Name FROM 
                                      Time_Sheet_Details__c where Hours__c > 0 Group by  Project__r.Name, Project__c];
        for(AggregateResult aggr: tsdtl){
            ProjectHoursWrapper aWraper = new ProjectHoursWrapper() ; 
            aWraper.projectId = (Id)(aggr.get('Project__c'));
            aWraper.projectName = (String)(aggr.get('Name'));
            //  Id ProjectId = (Id)(aggr.get('Project__c'));
            //system.debug('tDetailsRegular' + tDetailsRegular.get((Id)(aggr.get('Project__c'))));
            tsdwrap.add(aWraper);    
        }

        return tsdwrap;
    }




    public Class ProjectHoursWrapper{
        @AuraEnabled
        public Id projectId {get;set;}
        @AuraEnabled
        public String projectName {get;set;}
        @AuraEnabled
        public decimal totalRegularHours {get;set;}
        @AuraEnabled
        public String totalOtherHours {get;set;}
    }
3

@Mohith 's answer is correct, but I'd like to add one thing. The pattern I prefer in these cases is the following

for(AggregateResult tDetailReg:tsdtlBillRgr){
    id key = (Id)(tDetailReg.get('Project__c'));

    //If there is no key, skip
    if(key == null) {
        continue;
    }

    if (!tDetailsRegular.containsKey(key)) {
        //If the key does not exist, add it
        tDetailsRegular.put(key, new List< AggregateResult >());
    }

    //Now that you know that the key exists, add to the existing
    (tDetailsRegular.get(key)).add(tDetailReg);

} 
| improve this answer | |
3

When you use Maps in apex, one of the things you should pay attention to is handling NULL pointer exceptions.

NULL pointer exceptions happen if your Map does not contain the key and when the access the value for it it comes as NULL. Any operation with NULL will throw a NULL POINTER from thereon.

You can easily reproduce a null pointer using below code

Map<String,String> testNUllMap = new Map<String,String>();
testNUllMap.put('2', '2');
testNULLMap.get('1').length();// This will throw an exception since you are trying to perform an operation on null value

Your apex code can be fixed using below code and handling null and adding keys to Map as shown below

Map <Id, List <AggregateResult>> tDetailsRegular = new Map <Id, List <AggregateResult>>();

for (AggregateResult tDetailReg: tsdtlBillRgr) {
Id key = (Id)(tDetailReg.get('Project__c'));
// Maps can hold NULL as keys and hence we need this check
if (key != null) {
    // If the key is present we add to the list that exists against it
    if (tDetailsRegular.containsKey(key)) {
        tDetailsRegular.get(key).add(tDetailReg);
    } else {
        //Initialize list as no key is found before and first time we get key 
        List <AggregateResult> lstaggregateResults = new List <AggregateResult>();
        lstaggregateResults.add(tDetailReg);
        tDetailsRegular.put(key, lstaggregateResults);
    }
  }
}
| improve this answer | |
  • 2
    No, your first example will not result in a NullPointerException (without further code, at least). Also, this code simply won't work as is, the entire map will be empty. Also also, a null key is a potentially valid key, and won't necessarily throw an exception. – sfdcfox May 26 at 18:02
  • 1
    @sfdcfox Thanks !!! I just fixed the code and tested it after I had a closer look at the code. – Mohith Shrivastava May 26 at 18:31

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.