allegjdm93
allegjdm93

Reputation: 602

"#{serviceCatalogueController.allMap[category.key]}": Property 'key' not found on type java.util.HashMap$KeySet

I am trying to populate a map with values from inputText and inputTextArea. Also Date. In the backbean I have a map of like Map>

Basically, a Category can have many Attributes. These Attributes are input fields. For multiselect, dropdown and single select all i need is to set the attribute. But for TextArea, textField and Date I need to set the attribute plus the value which is why I have the String.

my jsf looks like

              <p:dataList id="serviceCatalogueCriteria" var="category" value="#{serviceCatalogueController.allMap.keySet()}">
                    <div id="categoryDiv" style="overflow: hidden;">
                        <div class="category-header">
                            <h:outputText value="#{serviceCatalogueController.allMap[category.key]}" />
                        </div>
                        <div>
                            <!-- Text field, text area or date -->
                            <div class="category-text">
                                <ui:fragment
                                    rendered="#{categoryService.isTextField(category) or categoryService.isTextArea(category) or categoryService.isDate(category)}">
                                    <ui:fragment
                                        rendered="#{categoryService.isTextField(category)}">
                                        <p:dataList var="attribute" value="#{category.entrySet()}" >
                                            <p:inputText 
                                                value="#{category[attribute.key]}" />
                                        </p:dataList>
                                    </ui:fragment>
                                    <ui:fragment
                                        rendered="#{categoryService.isTextArea(category)}">
                                        <p:dataList var="attribute" value="#{category.entrySet()}" >
                                            <p:inputTextarea rows="3" cols="70"
                                                value="#{category[attribute.key]}"/>
                                        </p:dataList>
                                    </ui:fragment>
                                    <ui:fragment rendered="#{categoryService.isDate(category)}">
                                        <p:dataList var="attribute" value="#{category.entrySet()}" >
                                            <p:calendar
                                                value="#{category[attribute.key]}"
                                                showOn="button">
                                            </p:calendar>
                                        </p:dataList>
                                    </ui:fragment>
                                </ui:fragment>
                            </div>
                    <p:separator />
                </p:dataList>

And my back bean looks like

private Map<Category,Map<Attribute,String>> allMap;
//setter and getter

The error I get is

javax.el.PropertyNotFoundException: /resources/PWAssessment/ServiceCatalogueFilters.xhtml @24,84 value="#{serviceCatalogueController.allMap[category.key]}": Property 'key' not found on type java.util.HashMap$KeySet

Why would this not work?

Upvotes: 0

Views: 1842

Answers (1)

BalusC
BalusC

Reputation: 1109645

There are 2 mistakes.

  1. <p:dataList> can't iterate over a Set<E> (nor Map<K, V>). It can only iterate over List<E> or E[] or DataModel<E>.

  2. Even if it would have worked, the var="category" represents the Category instance itself, not some Map. If the <p:dataList> would have supported Set<E>, you should just have used

    <h:outputText value="#{serviceCatalogueController.allMap[category]}" />
    

    And, equivalently, further in the code, the #{category.entrySet()} wouldn't have worked either, as the #{category} would represent the Category instance itself.

The <p:dataList> supports iterating over an array. So, this should do:

<p:dataList value="#{serviceCatalogueController.allMap.entrySet().toArray()}" var="categoryEntry">
    This is Category: #{categoryEntry.key}
    This is Map&lt;Attribute,String&gt;: #{categoryEntry.value}
    ...
    <p:dataList value="#{categoryEntry.value.entrySet().toArray()}" var="attributeEntry">
        This is Attribute: #{attributeEntry.key}
        This is String: #{attributeEntry.value}

This is quite inefficient though. I strongly recommend to remodel the model as such that you just have something like a List<CategoryDTO>. Otherwise, grab <c:forEach> which supports efficiently iterating over a Map:

<c:forEach items="#{serviceCatalogueController.allMap}" var="categoryEntry">
    This is Category: #{categoryEntry.key}
    This is Map&lt;Attribute,String&gt;: #{categoryEntry.value}
    ...
    <c:forEach items="#{categoryEntry.value}" var="attributeEntry">
        This is Attribute: #{attributeEntry.key}
        This is String: #{attributeEntry.value}

Upvotes: 2

Related Questions