#Spring Boot: Dropdown options appear in random order

26 messages · Page 1 of 1 (latest)

candid widget
#

Dropdowns map for sort dropdown options.

class Dropdowns {
  public final LinkedHashMap<String, String> orderMap = new LinkedHashMap<>(Map.of(
      "noviji", "Prvo najnoviji",
      "popularni", "Prvo najpopularniji",
      "skuplji", "Po ceni opadajuće",
      "jeftiniji", "Po ceni rastuće",
      "veći", "Po površini opadajuće",
      "manji", "Po površini rastuće"
  ));
}

list method calls listModel method which adds orderMap to the Model.

public class ListingController extends BaseController {
    private final Dropdowns dropdowns;
    // ...

    // Main
    @GetMapping("")
    public String list(Model model, Authentication auth,
        @RequestParam(name = "strana", defaultValue = "0", required = false) int pageNum,
        @RequestParam(name = "redosled", defaultValue = "noviji", required = false) String order) {
        // 4 Authentication & authorization
        Object user = currentUser(auth);

        Page<Listing> page = listingServ.findAll(pageNum, order);
        listModel(model, page, order);

        // 5 Security logging
        logger.info("User {} viewed all listings.", user);
        return "listings/listing_list";
    } // [1]

    private void listModel(Model model, Page<Listing> page, String order) {
        ListingSearchDTO searchDTO = new ListingSearchDTO();
        List<Listing> listings = page.getContent();

        model.addAttribute("orderMap", dropdowns.orderMap);
        model.addAttribute("order", order);
        model.addAttribute("page", page);
        model.addAttribute("searchDTO", searchDTO);
        model.addAttribute("listings", listings);
    } // [1]
}

1/2

spiral mirageBOT
#

This post has been reserved for your question.

Hey @candid widget! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 720 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

candid widget
#

Sort dropdown:

<!-- Sort select -->
<form class="mb-3 w-50" method="get" novalidate th:fragment="sort">
  <th:block th:if="${searchDTO != null}">
    <input type="hidden" name="grad" th:value="${searchDTO.getCity()}">
    <input type="hidden" name="brojSoba" th:value="${searchDTO.getRoomCount()}">
    <input type="hidden" name="m2Od" th:value="${searchDTO.getM2From()}">
    <input type="hidden" name="m2Do" th:value="${searchDTO.getM2To()}">
    <input type="hidden" name="cenaOd" th:value="${searchDTO.getPriceFrom()}">
    <input type="hidden" name="cenaDo" th:value="${searchDTO.getPriceTo()}">
  </th:block>

  <select class="form-select" name="redosled" onchange="this.form.submit()">
    <option th:each="entry : ${orderMap}" th:value="${entry.key}" th:selected="${entry.key == order}">[[${entry.value}]]</option>
  </select>
</form>

Select options appear in incorrect order (not like it's in Dropdowns class).

agile notch
#

The problem is that Map.of() already is unsorted an will destroy the order. If you want to ensure the order, you need to add the key-value pairs one by one in the correct order to the LinkedHashMap.

#

Or I don't understand what your problem is. Not sure about that.

candid widget
#

The sort dropdown options do not appear in correct order. They should be in this order:

"noviji", "Prvo najnoviji",
"popularni", "Prvo najpopularniji",
"skuplji", "Po ceni opadajuće",
"jeftiniji", "Po ceni rastuće",
"veći", "Po površini opadajuće",
"manji", "Po površini rastuće"
#

So how do I initialize LinkedHashMap without adding entries one by one?

spare swan
agile notch
#

Java should add a SequencedMap.of().

#

In olden days people did this with double brace initialisation:

public final LinkedHashMap<String, String> orderMap = new LinkedHashMap<>() {{
  put("noviji", "Prvo najnoviji");
  put("popularni", "Prvo najpopularniji");
  ...
}};

But this is frowned upon.

spare swan
#

because having static methods with the same name on subtypes is a bit confusing as recompiling changes behaviour with the same source code

#

and map factories are a bit odd anyway

#

Also that would probably be an immutable one, not a LinkedHashMap

#

you are free to write all 11 versions by yourself though

agile notch
#

Yeah, they'd need an additional implementation because currently they have this probing thing with the twice-as-big array. Whenever I need an immutable Map with strict insertion order, I use Guava ImmutableMap.

spare swan
#

I think Map.of even randomizes the order

#

but that's an unmodifiable view

#

whereas the question was about a mutable Map I think

agile notch
#

The question was why the order is destroyed at all.

spiral mirageBOT
#

💤 Post marked as dormant

This post has been inactive for over 720 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.
In case your post is not getting any attention, you can try to use /help ping.
Warning: abusing this will result in moderative actions taken against you.

candid widget
#

I did this, but it's kinda counter-intuitive.

public final LinkedHashMap<String, String> orderMap;

@Autowired
public Dropdowns(ItemService service) {
    itemList = service.findAll();

    this.orderMap = new LinkedHashMap<>();
    this.orderMap.put("noviji", "Prvo najnoviji");
    this.orderMap.put("popularni", "Prvo najpopularniji");
    this.orderMap.put("veći", "Po površini opadajuće");
    this.orderMap.put("manji", "Po površini rastuće");
    this.orderMap.put("skuplji", "Po ceni opadajuće");
    this.orderMap.put("jeftiniji", "Po ceni rastuće");
}
spare swan
#

alternatively

orderMap = Stream.of(Map.entry(...), Map.entry(...), ...)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a,b)-> a, LinkedHashMap::new));
#

which means

  • create a Stream of Map.Entrys (each with a key and value
  • convert it to a Map
    • the key is the entry key
    • the value is the entry value
    • in case of duplicates, pick the first
    • create a LinkedHashMap for ordering