XPages: compositeData is undefined

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>
Dieser Beitrag wurde unter Java, JSF, ServerSide JavaScript, XPages abgelegt und mit , , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.