+ Start a Discussion
Tye HarrisonTye Harrison 

Visualforce page uses old apex variable value but I see new value in debug logs. Why?

I have two VF pages. They are both controlled by an Apex class. The first page has many prepopulated fields that the user can change. The second page is a differently layed out page using the updated data but saved as a PDF attachment. I would post but it's over 1000 lines of code.

My situation/question is this:
The user edits the first VF page and clicks submit. Once the data passes some sanity checks it is saved. I can see all of these saved values in the Apex controller in the System.debug logs I generate. All values are the expected values from the user edits.
However, when I generate/save the PDF, all the values are correct *except* the values from two picklists (which are country code address single picklists). These values appear in the PDF page as the value that was previously on the user editable page (in other words, the value *before* the user edited the page). The strange thing is that when I look at the incorrect values/variables in the debug, they are the update values. I am calling the PDF generation code immediately after the above mentioned System.debug.
So, does anyone have an idea why the original values from the first VF page are used instead of the updated values I see in the logs? All the other values are the updated values.

I can try to post code snippets if needed but it's a lot to post here. 
Shashikant SharmaShashikant Sharma
Please post the code that will help in trcaing the issue.
Tye HarrisonTye Harrison
Thank you, Shashikant. I had to split this into two posts because of the character limit. 

I've tried to condense the code to its essentials. The problems area denoted by ' ==> ' in the left margin.


==> The apex code below is part of a larger class. The two variables that I don't understand the behavior are application.Shipping_Country__c & application.Billing_Country__c. Basically, when these variables are used in the first pageReference, "/apex/MembershipApplication" the page uses the user selected, new items. This is expected. However when the other pageReference is called, '/apex/MembershipApplicationPDF' , the page uses the old variables used before the user edited. This is despite the fact that the debug log that I call at the beginning of the makePDF method shows the correct value in the Shipping_Country__c & Billing_Country__c. Additionally, the other address fields are work as expected. 


public PageReference customSave()
    {
        System.debug('starting custom save');
        Boolean isError = false;
       
        // do validations first   
       
        // since so many validations depend on the domains, do them first and return if a problem
        Boolean isDomainError = false;
        isDomainError = isDomainValidated( application.Approved_Company_Domains__c, application.Website__c );
        if ( isDomainError )
        {
            return null;
        }
       
        isError = isValidated( memberList, application.Approved_Company_Domains__c );
        System.debug('after validations: isError: ' + isError);
                 
        // have we encountered any problems to address before saving?
        if ( isError )
        {
            // if yes, return to the page and display the error message
            System.debug( 'did not pass validations...');
            return null;
        }
       
        try
        {
            // expire the applicaton to prevent re-edits...
            application.Application_Expiration_Date__c = Date.Today() - 1;
           
            if ( newContactList != null && newContactList.size() > 0 )
            {
                    system.debug('inserting new contacts: ' + newContactList);
                    upsert newContactList;
            }
            if ( existingContactList != null && existingContactList.size() > 0 )
            {
                    system.debug('updating existing contacts: ' + existingContactList);            
                    upsert existingContactList;
            }
            if ( inactiveContactIdList != null && inactiveContactIdList.size() > 0 )
            {
                userList = getUsersForDeactivation( inactiveContactIdList );
                if ( userList != null && userList.size() > 0 )
                {
                    for ( User u : userList )
                    {
                        u.Portal_Access__c = 'Inactive';
                        u.IsActive = false;    
                    }
                    system.debug('updating users: ' + userList );
                    update userList;
                }                      
            }
           
            // if no problem, save the application
            system.debug( 'updating application: ' + application );
   application.Submitted__c = true; 
            update application;

            system.debug('shipping address country: ' + application.Shipping_Country__c);
            system.debug('billing  address country: ' + application.Billing_Country__c );
           
        }
        catch(Exception e)
        {
            System.debug('caught exception saving MMA Application: ' + e.getMessage() );
            MessageHelper.addError( 'Encountered a problem saving the Membership Application.  The error was: ' + e.getMessage() );
            return null;                   
        }
      
       
        PageReference pageRef = new PageReference('/apex/MembershipApplication');
        pageRef.setRedirect( false );
        System.debug( 'setting redirect to: ' + pageRef.getUrl() ); 
        MessageHelper.addStatus( 'Application Submitted');
       
        // set the submitted flag to "true" to show the confirmation message; make it "expired" to make fields read-only when viewing confirmation
        isSubmitted = true;
        isExpired = true;
       
        // let's remove any empty members from the list that were never used so we don't see empty rows in the Contacts on the confirmation screen
        List<MemberWrapper> tmpMembers = new List<MemberWrapper>();
         tmpMembers.addAll( memberList); // make a copy so we're not changing the list while looping...
        Integer i = 0;
        if ( tmpMembers != null && tmpMembers.size() > 0 )
        {
            System.debug( 'memberList size: ' + memberList.size() );
            for ( MemberWrapper wrapper : tmpMembers )
            {
                System.debug( 'tmpMembers size, position: ' + tmpMembers.size() + ' ,' + i);   
                        System.debug('looking for blanks: ' + wrapper.contact.firstname + ' ' + wrapper.contact.lastname );
               
                if ( wrapper.contact == null || (MessageHelper.isBlank( wrapper.contact.firstName) && MessageHelper.isBlank( wrapper.contact.lastName) ))
                {
                        selectedChildIndex = wrapper.index;
                        system.debug( 'removing blank wrapper at position: ' + wrapper.index + ' ' + wrapper );
                        removeChild();
                }      
                i++;
            }
        }      
       
        application.Shipping_Country__c = shippingCountryName;
        application.Billing_Country__c  = billingCountryName;       
       
  makePDF();
           
        // Once everything is verified and written create a PDF version of the MAP and store it in Membership Documents related list.
        //update application;
        return pageRef;
       
    } // end customSave
   
   
    public void makePDF() {
==> Here, I log the variables' values. They are the value we want. But when the PDF is generated it uses a previous value. I included the snippet of VisualForce code that uses this variable at the end of this post.
        System.debug('--> Start makePDF()');
        System.debug('Shipping_Country__c before PDF: "' + application.Shipping_Country__c +'"');
        System.debug('Billing_Country__c  before PDF: "' + application.Billing_Country__c +'"');
        System.debug('Shipping_Country_PDF__c before PDF: "' + application.Shipping_Country_PDF__c +'"');
        System.debug('Billing_Country_PDF__c before PDF: "' + application.Billing_Country_PDF__c +'"');
       
        PageReference pdf = new PageReference('/apex/MembershipApplicationPDF');
        Blob body;
       
        try {
            System.debug('Performing try pdf.getContentAsPdf()');
            body = pdf.getContentAsPdf();
        } catch (VisualforceException e) {
            System.debug('PDF Generation Error: ' + e);
            body = Blob.valueOf('Error : ' + e);
        }
        Id memDocId = null;
        for(Account accIt : [SELECT Id, Name, (Select Id, OwnerId, Name, Membership_Document__c, Document_Type__c From Membership_Documents__r) FROM Account WHERE Id=:AccountId]){
            for(Membership_Document__c md : accIt.Membership_Documents__r) {
                if (md.Document_Type__c == 'Membership Agreement') {  // If the related list already contains a Membership Agreement container then assign that.
                    memDocId = md.Id;
                }
                System.debug('--> MemDocs: ' + md);
            }
            if (memDocId == null) {  // If above related list had no container then create one in that related list.
                Membership_Document__c newMemDoc = new Membership_Document__c();   
                newMemDoc.Document_Type__c = 'Membership Agreement';
                newMemDoc.Name = 'Membership Agreement';
               
                newMemDoc.Membership_Document__c = accountId;
                insert newMemDoc;
                memDocId = newMemDoc.Id;
            }
           
            // insert the PDF attachment into the container that was created or found above.
            Attachment attach = new Attachment();
            attach.Body = body; 
            attach.Name = 'MAP - ' + application.Account_Name__c + ' ' + Datetime.now().format('yyyy-MM-dd HH:mm') + '.pdf';
            attach.isPrivate = false;
            attach.ParentId = memDocId;
            insert attach;
           
        }
        System.debug('--> End makePDF');
    }


Tye HarrisonTye Harrison
<!--  addresses, editable -->
            <apex:pageBlockSection columns="2" id="addresses" rendered="{!IF(NOT(isExpired), true, false) }">
                <apex:pageBlockSection title=" Headquarters Address (where your company is headquartered)" columns="1" id="hqAddress" collapsible="false"> 
                    <apex:outputpanel >
                        <table>
                            <tr>
                                <td Class="labelCol">
                                    <apex:outputPanel >
                                        <apex:outputPanel layout="inline" styleClass="theRequired">
                                            *                
                                        </apex:outputPanel>
                                        <apex:outputLabel value="{!$ObjectType.Membership_Application__c.Fields.Shipping_Street__c.label}" for="ShippingStreet"/>
                                    </apex:outputPanel>
                                 
                                </td>
                                <td>
                                    <apex:inputfield value="{!application.Shipping_Street__c}" id="ShippingStreet"/>
                                </td>
                            </tr>
                            <tr>
                                <td Class="labelCol">
                                    <apex:outputPanel >
                                        <apex:outputPanel layout="inline" styleClass="theRequired">
                                            *                
                                        </apex:outputPanel>
                                        <apex:outputLabel value="{!$ObjectType.Membership_Application__c.Fields.Shipping_City__c.label}" for="ShippingCity"/>
                                    </apex:outputPanel>
                                 
                                </td>
                                <td>
                                    <apex:inputField value="{!application.Shipping_City__c}" id="ShippingCity"/>
                                </td>
                            </tr>
                            <tr>
                                <td Class="labelCol">
                                    <apex:outputPanel >
                                        <apex:outputPanel layout="inline" styleClass="theRequired">
                                            *                
                                        </apex:outputPanel>
                                        <apex:outputLabel value="{!$ObjectType.Membership_Application__c.Fields.Shipping_State_Province__c.label}" for="ShippingState"/>
                                    </apex:outputPanel>
                                 
                                </td>
                                <td>
                                    <apex:inputField value="{!application.Shipping_State_Province__c}" id="ShippingState"/>
                                </td>
                            </tr>
                            <tr>
                                <td Class="labelCol">
                                    <apex:outputPanel >
                                        <apex:outputPanel layout="inline" styleClass="theRequired">
                                            *                
                                        </apex:outputPanel>
                                        <apex:outputLabel value="{!$ObjectType.Membership_Application__c.Fields.Shipping_Zip_Postal_Code__c.label}" for="ShippingPostalCode"/>
                                    </apex:outputPanel>
                                 
                                </td>
                                <td>
                                    <apex:inputField value="{!application.Shipping_Zip_Postal_Code__c}" id="ShippingPostalCode"/>
                                </td>
                            </tr>
                            <tr>
                                <td Class="labelCol">
                                    <apex:outputPanel >
                                        <apex:outputPanel layout="inline" styleClass="theRequired">
                                            *                
                                        </apex:outputPanel>
                                        <apex:outputLabel value="{!$ObjectType.Membership_Application__c.Fields.Shipping_Country__c.label}" for="ShippingCountry"/>
                                    </apex:outputPanel>
                                 
                                </td>
                                <td>
                                    <apex:selectList value="{!shippingCountryName}" size="1" id="ShippingCountry"  >
                                        <apex:selectOptions value="{!shippingCountries}" />
                                    </apex:selectList>
                                </td>
                            </tr>
                         
                        </table>
                    </apex:outputpanel>
                 
                    <script>
                    var ShippingStreet = '{!$Component.ShippingStreet}';
                    var ShippingCity = '{!$Component.ShippingCity}';
                    var ShippingState = '{!$Component.ShippingState}';
                    var ShippingPostalCode = '{!$Component.ShippingPostalCode}';
                    var ShippingCountry = '{!$Component.ShippingCountry}';
                    </script>

anup-prakashanup-prakash
Hi were you able to find a solution?
Shashikant SharmaShashikant Sharma
Over here issue is that you have made change in current vfp context and trying to create PDF with new page. 


System.debug('--> Start makePDF()');
        System.debug('Shipping_Country__c before PDF: "' + application.Shipping_Country__c +'"');
        System.debug('Billing_Country__c  before PDF: "' + application.Billing_Country__c +'"');
        System.debug('Shipping_Country_PDF__c before PDF: "' + application.Shipping_Country_PDF__c +'"');
        System.debug('Billing_Country_PDF__c before PDF: "' + application.Billing_Country_PDF__c +'"');
       
        PageReference pdf = new PageReference('/apex/MembershipApplicationPDF');


When PageReference pdf = new PageReference('/apex/MembershipApplicationPDF'); is called it will be a new page where you class level changes will not be saved. You need to save the changes in database ( update application; ) and fetch them from object using soql so they come in the pdf.
Tye HarrisonTye Harrison
anup-prakash: No solution yet.
Shashikant: It doesn't show in the version I posted above but I suspected what you suggest with (update application;) in a previous version. It didn't work. However, I'll have to see how I refetched them after update. Maybe something happened there. Thank you for the suggestion. I will take a look at this code again soon.