I am creating a Stash plugin using Soy to render a configuration UI. The servlet is calling the render-function with a LinkedHashMap which is populated in the JAVA code correctly. (printouts showing the correct order of elements)
render(resp, template, ImmutableMap.<String, Object>of("project", project, "data", data));
Example printout of data in JAVA function:
{1=[rep_1, rep_1], 11=[rep_2, rep_2], 12=[rep_3, rep_3], 21=[rep_4, rep_4]}
But when the render function has created the UI page from the Soy template the order of the elements in the passed HashMap is all wrong. I am doing a
{foreach $key in keys($data)} {$key} : {$data[$key]}<br> {/foreach}
and the elements are printed in some random order.
The order (as printed on the rendered UI page:
21 : [rep_4, rep_4]
1 : [rep_1, rep_1]
11 : [rep_2, rep_2]
12 : [rep_3, rep_3]
Isn't it possible to control the order the elements are accessed in the map in the Soy template?
Cheers,
// Svante
Community moderators have prevented the ability to post new answers.
Soy does not preserve the implementation of Maps it is provided. So even if you are using a `LinkedHashMap` or an `ImmutableMap` which have a stable iteration order, soy is not guaranteed to preserve the underlying implementations order.
If you want to have a collection or ordered things you are better to use a `List` instead. All `Iterable`s are converted to `List`s in soy so you can rely on their ordering.
Yep, this did the trick! I passed on an ArrayList of ArrayLists and now my order is correct, thnx! It is a bit more tricky to "unpack" this on the Soy side but it works with some clever logic!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I would think a little bit different and not sorting the Map, and instead sort the keys and send them to the Soy template as well.
You can do this with
SortedSet<Integer> keys = new TreeSet<Integer>(map.keySet());
Send the keys to the Soy template and render the Soy template like this:
{foreach $key in $keys} {$key} : {$map[$key]} : {index($key)}<br> {/foreach}
Cheers //M
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
What you want is a SortedMap - a HashMap doesn't guarantee order of the keys. Guava has an ImmutableSortedMap
class you can use to create these. By default a SortedMap will sort the keys in their "natural order", which is what you want in this case if you want them in integer order.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.