I'm trying to display records in panel2 after clicking a button in panel 1.But records are not displaying immediately after clicking a button.Initially panel2 displays empty,after refreshing page again it displays records.

Please see the below code and suggest where should I made mistake.

VF Page:

        <apex:outputPanel id="pg2" >
          <apex:outputPanel rendered="{!flag1}">
               <apex:commandButton value="Send Email" action="{!process}" reRender="pg1,pg2"/>
                    Generate and Assign Voucher
                    <apex:inputCheckBox value="{!checkBoxval}"/>

            <apex:outputPanel id="pg1" >
            <apex:outputPanel rendered="{!flag}" >
             <apex:repeat value="{!MyResult}" var="c" id="table"> 

                   <td data-label="Name">
                      <div class="slds-truncate" >{!c.Name}  </div>
                        <td scope="row" data-label="Email">
                          <div class="slds-truncate" >{!c.Login__c}</div>

Apex class :

 public PageReference process(){ 
       String query = 'SELECT Id,Login__c,Name,Priority__c,Opportunity__c,Opportunity__r.CloseDate, Attandance_Status__c,  WebinarContact__c,WebinarContact__r.Name,WebinarContact__r.Email,'+
                   'Voucher_Number__c,Email_Sent__c  FROM Webinar_Attendees__c WHERE Opportunity__c != Null  AND Attandance_Status__c = \'Attended\' ';
       Database.executeBatch(new VoucherGenerate_AssignBatch(query));

       flag = true;  
       flag1 = false ; 


Batch Job :

global with sharing class VoucherGenerate_AssignBatch implements Database.Batchable<SObject>, Database.Stateful {

    String query;
    public VoucherGenerate_AssignBatch(String query) {this.query=query;}

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(this.query); 
global void execute (Database.BatchableContext bc, List<Webinar_Attendees__c> scope) {}
global void finish(Database.BatchableContext batchableContext) {} 

Batch classes execute asynchronously. That is the design intention and purpose of Batch Apex. As a consequence, your Batch class will not have finished running when your Visualforce page rerenders, and any results that its real execute() method persists won't be available.

If you must execute this functionality using a batch class, you will need to either

  • Capture the Job Id returned by Database.executeBatch() and poll the AsyncApexJob associated with it to monitor its success or failure, and refresh your page only when it completes its operation. You might want to use an <apex:actionPoller> component to trigger the polling action, store state in your controller to mark the job as in-progress or completed, and conditionally render different page elements to relay that status to the user.
  • Have your Batch class fire a Platform Event in its finish() method, subscribe to it via JavaScript on your page, and update (perhaps with JavaScript Remoting, or an <apex:actionFunction>) your page's data when you receive notification of completion.

Either way, there's a fair amount more code, and more complex code, that you'll need to write here to achieve this objective. If your operation is small enough to be run synchronously rather than via Batch Apex, consider doing so.

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.