Mar 2, 2011 10:52 AM
261 Posts

Accessing the compositeData object (of a custom control) in the beforeRenderResponse event

  • Category: Server Side JavaScript
  • Platform: All
  • Release: 8.5.2
  • Role: Developer
  • Tags: custom control events
  • Replies: 3
Today I came across a strange issue when working with custom controls in an XPage. Try this:
  • create a custom control
  • add a simple print statement to the beforePageLoad event: print("beforePageLoad, compositeData is " + typeof compositeData);
  • add a simple print statement to the beforeRenderResponse event: print("beforeRenderResponse, compositeData is " + typeof compositeData);
  • create an XPage and add the custom control to it and open it.
  • have a look at the output on the server console
You'll notice that the compositeData object is undefined in the beforeRenderResponse event. Am I missing something here?  The only way I can think of to get around this is to write the compositeData object to a viewScope variable in the beforePageLoad event.

Mar 2, 2011 12:00 PM
23 Posts
Re: Accessing the compositeData object (of a custom control) in the beforeRenderResponse e...
I agree with you that this should logically work but I think this is the answer: It doesn't work that way.


public void setBeforeRenderResponse(javax.faces.el.MethodBinding beforeRenderResponse)
Description copied from interface: FacesPageProvider
A server-only event triggered before the render response phase of the JSF lifecycle. Since it does not occur during processing of the control tree for the phase, the event will not have access to data published by controls in the XPage.
Mar 3, 2011 3:35 AM
261 Posts
Re: Accessing the compositeData object (of a custom control) in the beforeRenderResponse e...
Thanks for your response.

Strange that the beforeRenderResponse doesn't have access to the compositeData object and the before-/ afterPageLoad (which occur before the beforeRenderResponse) do. Writing the properties is need to a viewScope variable is a workaround I can live with.
Mar 13, 2011 4:53 AM
41 Posts
Re: Accessing the compositeData object (of a custom control) in the beforeRenderResponse e...
 Mark, if you do, be sure to make a copy of the object instead of storing a pointer... and if the compositeData includes any component or data source references, be sure to store a primitive-based alternative (i.e. just the data source variable or form / view name, component id / client id, etc.). Part of the renderResponse phase is serialization of the View, including the viewScope, so any objects you store in the viewScope need to be serializable.
By the way, we've learned a lot more just in the last couple weeks about what exactly takes place in the various JSF phases of the XPage lifecycle, and without delving too deep into the nuts and bolts of it, the reason the compositeData is only available in certain phases is because of the way that the UIIncludeComposite class adds all of the core components defined in the custom control to the component tree.
A similar, though slightly different issue is a minor timing complication with repeat controls: I had wondered for years why it seemed the only property of a repeat control that could not be set to a value binding via a theme is its value attribute... but over the last week, the reason became obvious. A repeat's value attribute determines what collection it will iterate, and the runtime must calculate that before it applies themes, otherwise all the component instances inside the repeat would be skipped when the theme properties are applied... each of those components is only specified once in the source XML, but a separate set of them must be added to the component tree for each instance of the collection, and by the time themes are applied, that process has already occurred, so the repeat itself no longer exists, except as basically a div that contains all of the child components (not even that, if you've specified that the repeat should be removed).
So your issue is similar: a custom control defines zero or more core controls (and zero or more other custom controls) that should be added to the component tree at runtime. By the time it's ready to render the response, that process is already complete, so the compositeData - the map used to tell the custom control how to add those child controls to the tree - is considered no longer needed.