Grafik Krystian
Grafik Krystian

Reputation: 231

Iterating over the list collection in thymeleaf

I'm trying to create a simple list that returns results from the controller from the List collection. Previously, I wrote each individual result from the list one by one, but I know that this is a bad practice according to the DRY principle. That's why I'm trying to change it. I'm not friends with thymeleaf.

I care that:

Please help. Thank you

  <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
    <head>
        <title>Bootstrap Example</title>
        <html xmlns:th="http://www.thymeleaf.org">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <link rel="stylesheet" type="text/css"
              href="css/font.css"/>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
        <script src="js/chart.js"></script>
        </head>
    <body>

    <div class="container">
        <h2>Cheapest Flight</h2>


        <div class="list-group">
            <a href="#" class="list-group-item ">

                <b><img th:src="@{'http://pics.avs.io/400/400/' + ${AirlineIataFirst} + '.png'}"></b>

        Bad code /////......

                <c><p th:text="'Airline:  ' + ${AirlineFirst}"/></c>
                <d><p th:text="'Price:  ' + ${PriceFirst}+ ${Currency}"/></d>
                <e><p th:text="'Departure:  ' + ${DepartureFirst} "/></e>
                <f><p th:text="'Return:  ' + ${ReturnFirst} "/></f>


            </a>

And what I'm trying to do :

<a href="#" class="list-group-item" th:if="${flight != null}" >

<b><img th:src="@{'http://pics.avs.io/400/400/' + ${AirlineIataFourth} + '.png'}"></b>


<li th:each="flights : ${flight}" th:text="${flight}"></li>
<li th:each="prices : ${price}" th:text="${price}"></li>
 <c><p th:text="'Airline:  ' + ${flight}"/></c>
 <d><p th:text="'Price:  ' + ${price}+ ${Currency}"/></d>
 <e><p th:text="'Departure:  ' + ${DepartureFourth} "/></e>
 <f><p th:text="'Return:  ' + ${ReturnFourth} "/></f>

Controller :

        model.addAttribute("Currency", flightDTO.getCurrency());
        model.addAttribute("flight", cheapFlyService.flightList(output));
        model.addAttribute("number", cheapFlyService.flightNumberList(output));
        model.addAttribute("return", cheapFlyService.returnAtList(output));
        model.addAttribute("departure", cheapFlyService.departureAtList(output));
        model.addAttribute("price", cheapFlyService.priceList(output));

Upvotes: 0

Views: 859

Answers (1)

riddle_me_this
riddle_me_this

Reputation: 9145

It doesn't seem to be valid HTML tags in the second case. Your <a> is never closed. Also, you should likely stay away from using things like <b> as it's very confusing (it's a deprecated way to bold text). Remove all of those types of tags as it's not valid HTML or just plain confusing.

Additionally, while it will work, the naming on the th:each is backwards. You should be passing multiple flights, and refer to just one flight:

Controller:

    model.addAttribute("currency", flightDTO.getCurrency());
    model.addAttribute("flights", cheapFlyService.flightList(output));
    model.addAttribute("numbers", cheapFlyService.flightNumberList(output));
    model.addAttribute("returns", cheapFlyService.returnAtList(output));
    model.addAttribute("departures", cheapFlyService.departureAtList(output));
    model.addAttribute("prices", cheapFlyService.priceList(output));

HTML:

<th:block th:each="flight : ${flights}">
    <span th:text=${flight.number}" th:remove="tag">[Flight Number]</span> <!-- or whatever property is that the Flight class may have.  Note the scoping. -->
</th:block>

But the major feedback is that the complete HTML would depend on how you have your data modeled. For example, if a flight has a property called routes, then you can iterate on routes with an inner loop in Thymeleaf. Otherwise, you are adding separate lists to the model and you would just call the toString method on each:

<th:block th:each="departure : ${departures}">
    <span th:text=${departure}" th:remove="tag">[This is calling toString() on the objects in the list]</span>
</th:block>

General debugging tip: start with things that work and gradually add. If something is broken and you are lost, take away everything until it works and re-add back in gradually until you find the culprit(s).

Upvotes: 1

Related Questions