Following with a previous post about triggers and order of execution, I want to review in this new post how the order of execution on a Visualforce page is. This time we need to distinguish between two different cases: Visualforce pages that perform a get request and those which perform a post request.
In this post I will explain how GET requests work. I will elaborate a second part of the post, talking about POST requests.
I have based my investigation on this page from Salesforce help, however the empirical results I have got are a bit different from what the help says, so I will try to explain everything that I have found in detail.
Once a visualforce page is requested through a GET request, the server will perform all these steps:
1. Evaluate constructors on controller and extensions: this is, if I am using an Apex class as controller or as a controller extension, their constructors will be first evaluated. Remember we can have multiple controller extensions in a single visualforce page. In that case, the order in which the constructors is evaluated, is the order in which they are indicated in the visualforce page definition.
For illustrating that, I have created the next visualforce page, with the next controller and extensions:
<apex:page controller="MyVFController" extensions="MyExtension1,MyExtension2"> hello! </apex:page>
public class MyVFController { public MyVFController() { System.debug('I am MyVFController constructor'); } }
public class MyExtension1 { public MyExtension1(MyVFController controller) { System.debug('I am MyExtension1 constructor'); } }
public class MyExtension2 { public MyExtension2(MyVFController controller) { System.debug('I am MyExtension2 constructor'); } }
As it was expected, I obtain the next debug log:
2. According to Salesforce help, the next step is, if there are custom components on page, evaluate constructors on controller and extensions. However, what I have found is that the component controller and extension constructors are executed before the visualforce page ones. For checking this, I have created the next component:
<apex:component controller="ComponentController" extensions="ComponentExtension1,ComponentExtension2"> <apex:attribute name="param1" description="This is my param1" type="String" assignTo="{!param1Component}"/> <p> Param1Component: {!param1Component} </p> <p> Param1ComponentCopy: {!param1ComponentCopy} </p> </apex:component>
public class ComponentController { public String param1Component {get; set;} public String param1ComponentCopy {get; private set;} public ComponentController() { System.debug('I am ComponentController constructor'); System.debug('The value of param1Component is: ' + param1Component); param1ComponentCopy = param1Component; } }
public class ComponentExtension1 { public ComponentExtension1(ComponentController controller) { System.debug('I am ComponentExtension1 constructor'); } }
public class ComponentExtension2 { public ComponentExtension2(ComponentController controller) { System.debug('I am ComponentExtension2 constructor'); } }
I have modified the visualforce page I created for the first example to include the component, and also I have modified its constructor for having to set a parameter first:
<apex:page controller="MyVFController" extensions="MyExtension1,MyExtension2"> hello! <c:OrderOfExecution param1="{!param1}"/> </apex:page>
public class MyVFController { public String param1 {get; private set;} public MyVFController() { System.debug('I am MyVFController constructor'); param1 = 'lalala'; } }
If I open the visualforce page, I see this:
And if I take a look at the debug log that has been generated, I see the next:
So, what this says to me is that:
- First, component controller and extensions constructors are evaluated, no matter if the parameters that are passed in to the component are being initialised in the visualforce page constructor (I read in a stackexchange answer that the component constructor was evaluated first in that case, but that is not what I have found in my tests).
- Second, visualforce page controller and extensions constructors are evaluated.
- Third, variables passed in with assignTo are passed to the component.
If you see in the example, we have found a common problem, parameters passed to a component controller through assignTo attribute, won’t be ready in the component controller constructor (or its extensions!).
3. The next step is evaluation of the action attribute on the <apex:page> component , expressions, and the required getter and setter methods.
In our example, apart from the {!param1} that we pass to the component and that has already been evaluated, we have the next expressions:
- {!param1Component}: this expression calls the param1Component getter in the component constructor. As param1Component was assigned a value with the assignTo attribute, we see in the rendered page that it has been correctly rendered.
- {!param1ComponentCopy}: this expression calls the param1ComponentCopy getter in the component constructor. As when the component constructor was executed, param1Component did not have a value yet, we see in the rendered page that the value of param1ComponentCopy is null.
Also I have modified a bit the page to include an action param:
<apex:page action="{!populateActionParam}" controller="MyVFController" extensions="MyExtension1,MyExtension2"> hello! <c:OrderOfExecution param1="{!param1}"/> {!actionParam} </apex:page>
public class MyVFController { public String param1 {get; private set;} public String actionParam {get; private set;} public MyVFController() { System.debug('I am MyVFController constructor'); param1 = 'lalala'; } public void populateActionParam() { System.debug('I am populating the actionParam var'); actionParam = 'I am a param populated within action attribute'; } }
Salesforce help says that the order of these evaluations (action page attribute and expressions in the page) is indeterminate. However in my experience I understood that the action param is always evaluated before any expression on the page. If I open the visualforce page, with the modifications I have done, I see the next:
That means the action param method must have been evaluated before the expressions in the page, because if not, I would not be able of seeing the last sentence.
But here is when I find the surprise. If I take a look at the debug log:
We see in this case the visualforce controller and extension constructors have been evaluated before the component ones! So in that case is totally true that the order is what the help suggests. However, we see that the action param attribute is evaluated even before the component constructor. So that is possibly wrong in the help.
4. Finally, if there is an on the page, create view state, and in the end, the HTML is sent to browser. We will talk about view state in the next post, in which I will go through visualforce order of execution for POST requests.
I have created this diagram according to my investigations, which is a bit different from the Salesforce help one, and which I hope will help to understand all of this:
Here is the link to the code in my GitHub repo.
Interesting investigation
LikeLike
Nice.!!! 1 question though.
You mentioned that “Salesforce help says that the order of these evaluations (action page attribute and expressions in the page) is indeterminate”. So, for this one, did you get to run the page multiple times and got the same result? The same result as stated : “visualforce controller and extension constructors have been evaluated before the component ones!”
LikeLike
Yes, I obtained the same result each time.
I think that with that sentence they really refer to the order in which expressions are evaluated. And I think that they wanted to not complicate too much the help explaining all specific use cases. However, the help explicitly says that:
1- First execute visualforce controllers constructors
2- Then component controllers constructors
3- Then action attribute and expressions (it is in this point when they say “the order of these evaluations is indeterminate”)
So despite there could be a possible indetermination within point 3 (per the help), sometimes 2 goes before 1, or 3 goes before 2, and that is not in the help.
Hope that helps.
Regards.
LikeLiked by 2 people
Interesting to see your findings in this area. I’ve had a couple of goes with defining the order of execution –
* Unexpected Visualforce Order of Execution with component attributes on Get Request
– http://salesforce.stackexchange.com/q/117374/102
* Visualforce Order of Execution for an apex:dynamiccomponent within an apex:component
– http://salesforce.stackexchange.com/q/145745/102
I generally go off this tip by Michael. Alderete:
“But in general, we say don’t depend on order-of-execution behavior…”
LikeLike
Hi Daniel, your first go confirms what I am saying here.
Your second one is a most complex scenario which I haven’t reflected in my diagram (because I didn’t test it!). Apparently, as your second component needs “componentvalue” to be passed in, it’s evaluated even before selectedValue is passed in with assignTo. So maybe I could add a decision shape just before the assignTo attribute, to reflect that. Will do some tests.
I understand that they say in general not depend on the order of execution, but there is a lot of official documentation of visualforce order of execution! So maybe they should clarify.
Regards and thanks for the contribution!
LikeLike
I faced the same issue, every time the component’s controller’s was being called. Nice explanation and research
LikeLike