<c:choose><c:when> in JSF page does not work, seems to always evaluate false

1.6k views Asked by At

In my JSF page I use <c:choose><c:when> tag to conditionally display content. However, it does not work as it seems to always evaluate false.

E.g.

<h:outputText value="#{pollInfo.active} -" />
<c:choose>
    <c:when test="#{pollInfo.active}">
        <h:outputText value="Active" />
    </c:when>
    <c:otherwise>
        <h:outputText value="Deactive" />
    </c:otherwise>
</c:choose>

There are for sure a few items with active=true, which is confirmed by <h:outputText>, but it just prints Deactive for all items. You can see the actual output in the following picture:

enter image description here

How is this caused and how can I solve it?

1

There are 1 answers

0
BalusC On BEST ANSWER

The symptoms and the screenshot suggests that the #{pollInfo} represents the currently iterated item of an iterating UI component such as <ui:repeat>, <h:dataTable>, <p:tabView>, <p:dataTable>, etc.

JSTL tags run during view build time, that moment when JSF component tree is built based on XHTML source code. The var attribute of such an iterating UI component is only available during view render time, that moment when HTML output is produced based on JSF component tree.

In other words, they don't run "in sync". The #{pollInfo} is always null during view build time.

In this particular case, you need the JSF component's rendered attribute instead.

<h:outputText value="Active" rendered="#{pollInfo.active}" />
<h:outputText value="Deactive" rendered="#{not pollInfo.active}" />

Or if you intend to conditionally render larger pieces of code, wrap all in a <ui:fragment>:

<ui:fragment rendered="#{pollInfo.active}">
    <h:outputText value="Active" />
    <!-- Some more components here if necessary. -->
</ui:fragment>
<ui:fragment rendered="#{not pollInfo.active}">
    <h:outputText value="Deactive" />
    <!-- Some more components here if necessary. -->
</ui:fragment>

Again another alternative, given that you've a pure if-else, is using the conditional operator in EL:

<h:outputText value="#{pollInfo.active ? 'Active' : 'Deactive'}" />

Additional bonus is, you end up with much less code.

See also: