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
NVaefNVaef 

System.QueryException: List has no rows for assignment to SObject

Hey! So I'm running into this problem because there are no records to be pulled in my controller's aggregateresult string.

When I try to open a project with no attendee records I get the error, however If there are records, everything works fine.

 

I was thinking about using an if function or something similar. Any help would be greatly appreciated

 

Controller:

public class GaugeChartController {
    public String ProjId {get;set;}
 
    public GaugeChartController(ApexPages.StandardController controller){
        ProjId = controller.getRecord().Id;
    }
 
    public List<gaugeData> getData() {
          Integer TotalAttnds = 0;         
 
         AggregateResult Attendees = [select COUNT(Name) numAPJs
                                   from Attendee_Project_Junction__c
                                   where Project__c =: projId                                
                                   GROUP BY CALENDAR_MONTH(Event_Date__c) LIMIT 1];
 
          List<gaugeData> data = new List<gaugeData>();
          data.add(new gaugeData(Integer.valueOf(Attendees.get('numAPJs'))+ 'Attendees', Integer.valueOf(Attendees.get('numAPJs'))));    

          return data;
                                       
     }
 
    public class gaugeData {
        public String name { get; set; }
        public Integer size { get; set; }
 
        public gaugeData(String name, Integer data) {
            this.name = name;
            this.size = data;
        }
    }
}

SurpriseSurprise

I see you are passing paramaters to the constructor of the class.Though your constructor accepts string and integer as an argument.However,you are passinng integer twice as an argument where is the string value.

 

You have to correct that

 

Your code is not bulkified as you have specified limit 1.You should remove that let query run and then returned results should be captured in an aggreagate array.Having done that then you should run for loop to loop through  returned results and then extract the aggreagated values and send to the constructor of the other class.

 

Above given is going to be better design principle.

 

NVaefNVaef

public class GaugeChartController {
    public String ProjId {get;set;}
 
    public GaugeChartController(ApexPages.StandardController controller){
        ProjId = controller.getRecord().Id;
    }
 
    public List<gaugeData> getData() {
          Integer TotalAttnds = 0;         
 
         AggregateResult Attendees = [select COUNT(Name) numAPJs
                                   from Attendee_Project_Junction__c
                                   where Project__c =: projId                                
                                   GROUP BY CALENDAR_MONTH(Event_Date__c) ];                                   
 
          List<gaugeData> data = new List<gaugeData>();
          data.add(new gaugeData('Attendees', Integer.valueOf(Attendees.get('numAPJs'))));    

          return data;
                                       
     }
 
    public class gaugeData {
        public String name { get; set; }
        public Integer size { get; set; }
 
        public gaugeData(String name, Integer data) {
            this.name = name;
            this.size = data;
        }
    }
}

 

So that random bit of information is set and fixed, thank you. Do you have any insight on the problem I asked about?

Sean TanSean Tan

From a high level I suspect it's this line here:

 

 AggregateResult Attendees = [select COUNT

(Name) numAPJs
                                   from Attendee_Project_Junction__c
                                   where Project__c =: projId                                
                                   GROUP BY CALENDAR_MONTH(Event_Date__c) ];

 

Most likely this query isn't returning anything... you'll want to trap for that by casting it as a list of SObject's rather then a single SObject:

 

AggregateResult[] AttendeeList = [select COUNT (Name) numAPJs
                                   from Attendee_Project_Junction__c
                                   where Project__c =: projId                                
                                   GROUP BY CALENDAR_MONTH(Event_Date__c) ];
								   
if (!attendeeList.isEmpty())
{
	//Do logic with the items in the list
}

 

 

 

ForcepowerForcepower
NV, You could try what Sean suggested. One other option is to put your data.add line in a try - catch.
try {
data.add(new gaugeData('Attendees', Integer.valueOf(Attendees.get('numAPJs'))));
} catch (Exception e) {}

That would also take care of any issue where you do get a row but no aggregate value called "numAPJs".
Ram
ForcepowerForcepower
Actually, now that I see the error more clearly, it is exactly as Sean suggested - no rows being returned on the aggregation query.
NVaefNVaef

Hey Sean,

 

So this error was preventing me from opening a project that didn't have an Attendee Record previously in it. With the if statement, what logic would I use to just push through to the page or display a 0 when it recognizes that there are no rows?

 

Sorry for the continuous silly questions, my coding experience started last week.

ForcepowerForcepower

Try this:
if (!attendeeList.isEmpty())
{
    //Do logic with the items in the list
        data.add(new gaugeData('Attendees', Integer.valueOf(attendeeList[0].get('numAPJs'))));   
}

else
        data.add(new gaugeData('Attendees', 0));  

NVaefNVaef

So I got this error - Error: Compile Error: Variable data is used before it is declared. at line 8 column 38

 

Here are the relevant lines starting from 8

 

public List<gaugeData> getData() {
Integer TotalAttnds = 0;

AggregateResult[] AttendeeList = [select COUNT (Name) numAPJs
from Attendee_Project_Junction__c
where Project__c =: projId
GROUP BY CALENDAR_MONTH(Event_Date__c) ];

if (!attendeeList.isEmpty())
{
data.add(new gaugeData('Attendees', 0));
}

List<gaugeData> data = new List<gaugeData>();
data.add(new gaugeData('Attendees', Integer.valueOf(Attendees.get('numAPJs'))));

return data;

ForcepowerForcepower
Just move the line
List<gaugeData> data = new List<gaugeData>();

to right after
Integer TotalAttnds = 0;
NVaefNVaef

Excellent, that worked! thank you