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
Michael MMichael M 

Error: List has no rows for assignment to SObject Error is in expression '{!makePostCallout}' in component <apex:commandButton> in page emedspage: Class.EMedCalloutsExtension.makePostCallout: line 15, column 1

Hello, I am getting this error message when click on the button on my VF page:
List has no rows for assignment to SObject
Error is in expression '{!makePostCallout}' in component <apex:commandButton> in page emedspage: Class.EMedCalloutsExtension.makePostCallout: line 15, column 1
How can I fix this? 

Here is my page and controller. I will bold the line 15 of the controller. 
PAGE

CONTROLLER
public class EMedCalloutsExtension {
    
    public final Lead referral;
    public String requestLabel;
        public String result {get;set;}
        public List<Object> emedData {get;set;}
    

     Public EMedCalloutsExtension(ApexPages.StandardController stdController){
        this.referral = (Lead)stdController.getRecord();
          //   Lead ref =[Select Id, Name from Lead where Id = :this.referral.id];   
         
  }
       public Object  makePostCallout() {
    Lead ref =[Select Id, firstname, lastname, gender__c, patient_dob__c, patient_ssn__c from Lead where Id = :ApexPages.currentPage().getParameters().get('id')];   
         

           String ssnReplace = ref.Patient_SSN__c.replace('-','');
           String genderLetter;
           if (ref.Gender__c == 'Male'){
               genderLetter = 'M';
           } else if (ref.Gender__c == 'Female'){
               genderLetter = 'F';
           }
            String d = String.valueOf(ref.Patient_DOB__c);
                 d.replace('-','');
           
           Map<string, string> patientInfoMap = new Map<string, string>();
                           patientInfoMap.put('first_name', ref.firstname);
                          patientInfoMap.put('last_name', ref.lastname);
                          patientInfoMap.put('gender', genderLetter);
                          patientInfoMap.put('birthdate', d);
                          patientInfoMap.put('social_security_number', ssnReplace);
           List<Object> patientInfoList = new List<Object>();
           patientInfoList.add(patientInfoMap);
           
           JSONGenerator gen = JSON.createGenerator(true);   
              gen.writeStartObject();     
             gen.writeStringField('processing_mode', 'Realtime');
             gen.writeStringField('request_type', '270');
             gen.writeStringField('information_source_id', '1');
             gen.writeStringField('submitter_system_id', '2');
             gen.writeStringField('submitter_system_type', 'api');
             gen.writeStringField('submitter_request_id', 'R1');
            gen.writeObjectField('subscribers', patientInfoList);
                 gen.writeEndObject();   
            String jsonS = gen.getAsString();
        System.debug('jsonMaterials'+jsonS);
          
        Continuation con = new Continuation(40);
        con.continuationMethod='processResponse';

       HttpRequest req = new HttpRequest();
        req.setEndpoint('https://............(intentionally left out)');
        req.setMethod('POST');
        req.setBody(jsonS);
       Http http = new Http();  
         this.requestLabel = con.addHttpRequest(req);
     // HTTPResponse res = http.send(req);
       return con; 
   
 /*   String result = null;
    Integer statusCode = res.getStatusCode();
          system.debug('statusCode is ' + statusCode);
   if(statusCode == 200){
             system.debug('API invoked successfully');
    result = res.getBody();
      } 
           return result;      */     
    }
    
 public Object processResponse() {  
        HttpResponse response = Continuation.getResponse(this.requestLabel);
 Integer statusCode = response.getStatusCode();
    system.debug('statusCode is ' + statusCode);
        // Set the result variable that is displayed on the Visualforce page
        if (statusCode == 200) {
             system.debug('statusCode is ' + statusCode);
            this.result = response.getBody();
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            emedData = (List<Object>) results.get('emedData');
        }
        return null;
     
     
     
    }

}
 
Best Answer chosen by Michael M
David Zhu 🔥David Zhu 🔥
Value attribute of apex:pageblocktable component is a collection of data. 

https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_pageBlockTable.htm

In your case, emedData should be a list data type. E.g. List<wrapperClass>. 

let define the class as below x

Public class WrapperClass
{
.    Public string item {get;set;}
      ……
     ……
}
In vf page, change this line:
<apex:pageBlockTable value="{!results }" var="an">
<apex:column value="{!an}". Should be <apex:column value="{!an.item}"

In apex method:
public list<wrapperclass> results {get;set;}
public void makePostCallout{
// Your code here

   // Build your data and assign to class variable results.
}

All Answers

Michael MMichael M
I forgot to attached the vf page. Here it is:
<apex:page standardController="Lead" extensions="EMedCalloutsExtension" lightningStylesheets="true">
        <apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons >
                <apex:commandButton action="{!makePostCallout}" value="Make Callout" reRender="detail"/>
               
            </apex:pageBlockButtons>
            <apex:pageBlockSection id="detail" columns="1">
                 {!result }
                <br/>  <br/> 
                 <apex:pageBlockTable value="{!emedData }" var="an">
                     <apex:column value="{!an}" headerValue="EMed Info"/>
                 </apex:pageBlockTable>
                
            </apex:pageBlockSection>
       
        </apex:pageBlock>
   
    </apex:form>
</apex:page>
David Zhu 🔥David Zhu 🔥
Value attribute of apex:pageblocktable component is a collection of data. 

https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_pageBlockTable.htm

In your case, emedData should be a list data type. E.g. List<wrapperClass>. 

let define the class as below x

Public class WrapperClass
{
.    Public string item {get;set;}
      ……
     ……
}
In vf page, change this line:
<apex:pageBlockTable value="{!results }" var="an">
<apex:column value="{!an}". Should be <apex:column value="{!an.item}"

In apex method:
public list<wrapperclass> results {get;set;}
public void makePostCallout{
// Your code here

   // Build your data and assign to class variable results.
}
This was selected as the best answer
Michael MMichael M
Thank you for your response.
1.  I don't understand what I need to do. Would you be able to show me how to write it/ how to incorporate what you said with what I already have?
2. My query on line 15 (Lead ref =[Select Id, firstname, lastname, gender__c, patient_dob__c, patient_ssn__c from Lead where Id = :ApexPages.currentPage().getParameters().get('id')]; ) is still returning 0 results. How can I change it to recognize the ID of the current record? 
 
David Zhu 🔥David Zhu 🔥
For your second qeustion, please check if the url has the yellow highlighted part.
User-added image
ApexPages.currentPage().getParameters().get('id') is get the parameter from url. 
 
Michael MMichael M
I do see an id in the url, but still am getting the error:
User-added image
David Zhu 🔥David Zhu 🔥
your url missing id in it.

try

....../apex/EmedsPage?id=xxxxxxxx
 
Michael MMichael M
I see! That seemed to work- it is not showing an error anymore. However, now, when I click the button, nothing happens... Which I guess may be related to question 1. 
David Zhu 🔥David Zhu 🔥
Yes. then you can refer to my orignal reply to fix other issues.
Michael MMichael M
Sure, just to clarify, are you saying I should delete the methods in my extension class? I'm not sure I understood your advice.. if you don't mind.
Michael MMichael M
I changed my class, and set up debug logs. The logs are saying that my response code is "502" (Bad Gateway Error.)

Here is my class and page now:
PAGE
<apex:page standardController="Lead" extensions="EMedCalloutsExtension" lightningStylesheets="true">
    <slds/>
        <apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons >
                <apex:commandButton action="{!makePostCallout}" value="Make Callout" reRender="detail"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection id="detail" columns="1">
                {!result }
                <br/>  <br/> 
                 <apex:pageBlockTable value="{!emedData }" var="an">
                     <apex:column value="{!an}" headerValue="EMed Info"/>
                 </apex:pageBlockTable>
                
            </apex:pageBlockSection>
       
        </apex:pageBlock>
   
    </apex:form>
</apex:page>

CLASS
public class EMedCalloutsExtension {
    
    public final Lead referral;
    public String requestLabel;
        public String result {get;set;}
        public List<Object> emedData {get;set;}
    

     Public EMedCalloutsExtension(ApexPages.StandardController stdController){
        this.referral = (Lead)stdController.getRecord();
          //   Lead ref =[Select Id, Name from Lead where Id = :this.referral.id];   
         
  }
       public Object  makePostCallout() {
    Lead ref =[Select Id, firstname, lastname, gender__c, patient_dob__c, patient_ssn__c from Lead where Id = :ApexPages.currentPage().getParameters().get('id')]; 
           system.debug('***NAME OF REFERRAL***: '+ ref.firstname + ' ' + ref.lastname);
    String ssnReplace; 
           if (ref.Patient_SSN__c != null){
            ssnReplace = ref.Patient_SSN__c.replace('-','');
           }
           String genderLetter;
           if (ref.Gender__c == 'Male'){
               genderLetter = 'M';
           } else if (ref.Gender__c == 'Female'){
               genderLetter = 'F';
           }
            String d = String.valueOf(ref.Patient_DOB__c);
               d.replace('-','');
           
           Map<string, string> patientInfoMap = new Map<string, string>();
                         patientInfoMap.put('first_name', ref.firstname);
                          patientInfoMap.put('last_name', ref.lastname);
                          patientInfoMap.put('gender', genderLetter);
                          patientInfoMap.put('birthdate', d);
                          patientInfoMap.put('social_security_number', ssnReplace);
           List<Object> patientInfoList = new List<Object>();
           patientInfoList.add(patientInfoMap);
           
           JSONGenerator gen = JSON.createGenerator(true);   
            gen.writeStartObject();     
             gen.writeStringField('processing_mode', 'Realtime');
             gen.writeStringField('request_type', '270');
             gen.writeStringField('information_source_id', '1');
             gen.writeStringField('submitter_system_id', '2');
             gen.writeStringField('submitter_system_type', 'api');
             gen.writeStringField('submitter_request_id', 'R1');
            gen.writeObjectField('subscribers', patientInfoList);
              gen.writeEndObject();   
         String jsonS = gen.getAsString();
        System.debug('***jsonMaterials***'+jsonS);
          
       // Continuation con = new Continuation(40);
        //con.continuationMethod='processResponse';

       HttpRequest req = new HttpRequest();
        req.setEndpoint('https:.............(left out)');
        req.setMethod('POST');
        req.setBody(jsonS);
       Http http = new Http();  
       //  this.requestLabel = con.addHttpRequest(req);
     HTTPResponse res = http.send(req);
      // return con; 
   
  String result = null;
    Integer statusCode = res.getStatusCode();
          system.debug('***statusCode is***: ' + statusCode);
   if(statusCode == 200){
             system.debug('***API invoked successfully***');
    result = res.getBody();
          system.debug('***RESULT***: ' + result);
      }   
           return result;   
        
    }
    
 public Object processResponse() {  
        HttpResponse response = Continuation.getResponse(this.requestLabel);
 Integer statusCode = response.getStatusCode();
    system.debug('***statusCode is ***:' + statusCode);
        // Set the result variable that is displayed on the Visualforce page
        if (statusCode == 200) {
             system.debug('statusCode is ' + statusCode);
            this.result = response.getBody();
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            emedData = (List<Object>) results.get('emedData');
        }
        return null;
     
     
     
    }

}
David Zhu 🔥David Zhu 🔥
make sure your end point is setup in Salesforce Remote Site Settings.
Michael MMichael M
It is in remote site settings. 

Do I need to be using the Continuation class for this? I commented it out, but am not sure if it would need to be used here. 
Michael MMichael M
Hi David, regarding your comment that emedData should be a list data type, isn't this already a list data type? 

        if (statusCode == 200) {
             system.debug('statusCode is ' + statusCode);
            this.result = response.getBody();
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            emedData = (List<Object>) results.get('emedData');
        }
David Zhu 🔥David Zhu 🔥
If variable this.results is Map<String,Object> data type., results.get('emedData') will give a Object not a List<Object>
Michael MMichael M
I see. Even though I am declaring it as a List<Object>? 
If I use a wrapper class, which parts of my current code would need to be moved to the wrapper class? 
David Zhu 🔥David Zhu 🔥
What exactly do you mean List<Object>?
Is it Map<String,List<Object>> results = .... ?

This will be depending on what the return data you get from reponse.getBody().

I would suggest you get the reponse body, and put in this URL to covert to a Apex class, from there, build you own wrapper class. 
https://json2apex.herokuapp.com/