I am using a visualforce email template from Apex Batch class. I am getting the Body of email when checking from Preview and Test mode. But if I schedule the batch, only blank email is coming. I am using visualforce component with custom controller inside my visualforce email template to prepare the email body.

Below is the code.

Email Template:

<messaging:emailTemplate subject="Pending Letter" recipientType="Contact" 
  <messaging:htmlEmailBody >
    <c:Pending_Letter caseId="{!relatedTo.Case__r.Id}" contactId={!relatedTo.Case__r.Contact.Id}"/>

Vf Component:

<apex:component access="global" controller="Reminder_Letter">
<apex:attribute name="contactId" type="Id" description="Id of the Contact" assignTo="{!contact}"/>
<apex:attribute name="caseId" type="Id" description="Id of the Case" assignTo="{!cId}"/>  
 <apex:dataTable value="{!returnList}" var="pr" id="dtCaseInfo"
                 rowClasses="odd,even" styleClass="tableClass">
    <apex:column >
        <apex:facet name="header"> Serial Number  </apex:facet>
        <apex:outputText value="{!pr.Issue__r.SerialNumber__c}"/>


public class Reminder_Letter {
public Id cId {get;set;}
public Id contact {get;set;}
List<Return__c> productReturnList;
Public List<Return__c> getReturnList(){            

   if(cId != null) {
       ReturnList = new List<Return__c>([Select   Id, Name,Return_Status__c, Issue__r.Serial_Number__c FROM  Return__c WHERE Return_Status__c  IN ('Pending') AND Case__c =: cId]);
       return ReturnList;
   return null;

Batch Class Code (for sending mail) : I am referring the VF email template using the following line. As the batch is working fine only sharing the portion related to email functionality.

 EmailTemplate et = [SELECT id FROM EmailTemplate WHERE developerName = 'Reminder_Letter'];


    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String [] toaddress = toStr;
    EmailTemplate et = [SELECT id FROM EmailTemplate WHERE developerName = 'Reminder_Letter'];
    mail.setSubject('Test email');

        results = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});   
    Catch(Exception e){
  • 1
    share your btach class code also. May be you are not passing correct parameters. Commented Apr 21, 2017 at 4:58
  • @Tushar Sharma - i am not sure how to pass parameters to vf template from batch.
    – CRM Guy
    Commented Apr 21, 2017 at 5:47
  • Thats why I asked you to share your batch code? Commented Apr 21, 2017 at 6:04
  • @TusharSharma: added it. Please check
    – CRM Guy
    Commented Apr 21, 2017 at 6:09
  • @TusharSharma- I am now adding custom setting to the component's construtor but it is not loading values. Could you please check?
    – CRM Guy
    Commented Apr 22, 2017 at 1:10

2 Answers 2


As you are using Email template so you need to remove this line

mail.setSubject('Test email');

It will override your template. So remove this line and you will get email body.

  • 1
    You rock !! it's working..
    – CRM Guy
    Commented Apr 21, 2017 at 6:50
  • I am now using custom setting to load mail body as per country settings and there It's not working as expected. Could you please check?
    – CRM Guy
    Commented Apr 22, 2017 at 1:09
  • @CRMGuy post it as separate question and tag me. Commented Apr 22, 2017 at 15:59

If you want to override only email subject not body, you can render your SingleEmailMessage like

Messaging.SingleEmailMessage message = Messaging.renderStoredEmailTemplate(templateId, whoId, whatId);
message.setSubject('Test email');

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .