An interesting question was asked on StackOverflow.com: The compositeData of custom control is undefined in beforeRenderResponse event. I have never noticed this before, but if you are accessing the compositeData object in the before-, afterRenderResponse or the afterRestoreView event, the object is undefined.
Here is a simple demonstration CC which just prints the type of the compositeData object to the console:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforePageLoad>
<![CDATA[#{javascript:print( "beforePageLoad: " + typeof( compositeData )) }]]>
</xp:this.beforePageLoad>
<xp:this.afterPageLoad>
<![CDATA[#{javascript:print( "afterPageLoad: " + typeof( compositeData )) }]]>
</xp:this.afterPageLoad>
<xp:this.afterRestoreView>
<![CDATA[#{javascript:print( "afterRestoreView: " + typeof( compositeData )) }]]>
</xp:this.afterRestoreView>
<xp:this.beforeRenderResponse>
<![CDATA[#{javascript: print( "beforeRenderResponse: " + typeof( compositeData )) }]]>
</xp:this.beforeRenderResponse>
<xp:this.afterRenderResponse>
<![CDATA[#{javascript: print( "afterRenderResponse: " + typeof( compositeData )) }]]>
</xp:this.afterRenderResponse>
</xp:view>
And here is a screenshot of the console, including a partial refresh of the page:
Only in the PageLoad events the compositeData object is available. But why?
The answer is rather simple: The events are executed in a different context. The PageLoad events are running „inside“ of the UIInlcudeComposite (the Custom Control), the other events are running in the UIViewRoot:
That’s why the compositeData is undefined in these events. To use the object in the events, you have to do the following:
First you have to add an ID to your custom control:
<xc:ccWithId test="foo" id="ccWithId" />
This allows you to access the CC as a regular component with getComponent(). Now you can access the com.ibm.xsp.binding.PropertyMap of the component in the custom control’s event which holds the variable you want:
<xp:this.beforeRenderResponse>
<![CDATA[#{javascript:
var cmp:com.ibm.xsp.component.UIIncludeComposite = getComponent("ccWithId");
print("Value of 'test' -> " + cmp.getPropertyMap().getString("test") )
}]]>
</xp:this.beforeRenderResponse>