Richard Roman
Richard Roman

Reputation: 53

Struts2 nested iterators

I am having trouble getting nested iterators to work. The inner iterator works on the first cycle of the outer iterator an then fails on subsequent cycle of the outer.

I am using Struts2 2.3.16.3.

package actions.test;

public class MainArray 
{
  private String mainVal_1="Main Hello";
  private String mainVal_2="Main World";
  private SubArray subArray;

  public SubArray getSubArray() { return subArray; }

  public void setSubArray(SubArray subArray) { this.subArray = subArray; }

  public String getMainVal_1() { return mainVal_1; }

  public String getMainVal_2() { return mainVal_2; }
}
package actions.test;

public class SubArray 
{
  private String subVal_1="Sub Hello";
  private String subVal_2="Sub World";

  public String getSubVal_1() { return subVal_1; }

  public String getSubVal_2() { return subVal_2; }
}
package actions.test;

import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport
{
  private static final long serialVersionUID = -5466515238282086387L;
  List<MainArray> mainArrayList = new ArrayList();

  public String execute()
  {
    SubArray sub1 = new SubArray(); 
    SubArray sub2 = new SubArray();
    SubArray sub3 = new SubArray();

    MainArray main1 = new MainArray();
    main1.setSubArray(sub1);

    MainArray main2 = new MainArray();
    main1.setSubArray(sub2);

    MainArray main3 = new MainArray();
    main1.setSubArray(sub3);

    mainArrayList.add(main1);
    mainArrayList.add(main2);
    mainArrayList.add(main3);

    return "success";
  }

  public List<MainArray> getMainArrayList()  { return mainArrayList;} 
}
<%@ taglib prefix="s" uri="/struts-tags" %>

<h1>Test</h1>

<s:iterator value="mainArrayList" >
  * <s:property value="mainVal_1"/>, 
    <s:property value="mainVal_2"/><br> 
    <s:iterator value="subArray">
    ** <s:property value="subVal_1"/>,      
       <s:property value="subVal_2"/><br>
    </s:iterator>
</s:iterator>

OUTPUT:

Test
* Main Hello, Main World
** Sub Hello, Sub World
* Main Hello, Main World
* Main Hello, Main World

Notice that the nested iterator only works on the first pass of the outer loop. I've tried a number of variations, such as adding var="main" to the outer loop. But I get the same result:

<%@ taglib prefix="s" uri="/struts-tags" %>

<h1>Test</h1>

<s:iterator value="mainArrayList" var="main">
  * <s:property value="mainVal_1"/>, 
    <s:property value="mainVal_2"/><br> 
    <s:iterator value="#main.subArray">
    ** <s:property value="subVal_1"/>,  
       <s:property value="subVal_2"/><br>
    </s:iterator>
</s:iterator>

Any thoughts on how to get this scenario to behave?

Upvotes: 1

Views: 788

Answers (2)

Andrea Ligios
Andrea Ligios

Reputation: 50193

From the Iterator documentation:

Iterator will iterate over a value. An iterable value can be any of: java.util.Collection, java.util.Iterator,

Despite the name, your SubArray is not an array, but a POJO.

Then simply use the Dot Notation to access it and its properties:

<s:iterator value="mainArrayList" >
  * <s:property value="mainVal_1"/>, 
    <s:property value="mainVal_2"/><br>
  ** <s:property value="subArray.subVal_1"/>,      
     <s:property value="subArray.subVal_2"/><br>
</s:iterator>

Also avoid mixing camelCase and snake_case in variable names. The best practice is to use camelCase only (eg. mainVal1, subVal1).

To know how to use the # and the other symbols in OGNL, read this answer.

Upvotes: 0

Zielu
Zielu

Reputation: 8552

You set your subarrays on the main1 only (but three times), so the other 2 have no subarray set and no output is produced.

Upvotes: 1

Related Questions