przemekost
przemekost

Reputation: 91

How to transfer informations, object to the thymeleaf

I'm develop an application JAVA + Spring Boot+ ThymeLeaf(easy and simple front just for test). I have got simple domain class Player:

@Entity
@Setter
@Getter
@EqualsAndHashCode(exclude = {"events"})
public class Player {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String playerName;
    private String playerLastName;
    private String playerNickname;
    private String playerEmailAddress;
    private String playerTelephoneNumber;

    @ManyToMany(mappedBy = "players", fetch = FetchType.EAGER)
    private Set<Event> events = new HashSet<>();

    @Enumerated(value = EnumType.STRING)
    private FavouritePosition favouritePosition;
    private LocalDate birthdayDate;

}

I would like to calculate player age in "service" class.

The question is: how to tranfer this information to the frontend?

Controller method look like this:

@RequestMapping("/event/{eventId}/player/{playerId}/show")
    public String showPlayerForSpecificTeam(Model model, @PathVariable String eventId, @PathVariable String playerId) {

        model.addAttribute("player", playerService.getPlayerByEventIdAndPlayerId(Long.valueOf(eventId), Long.valueOf(playerId)));

        return "event/player/showPlayerForSpecifiedEvent";
    }

Where method getPlayerByEventIdAndPlayerId(Long.valueOf(eventId), Long.valueOf(playerId))return the Player object (there are no age just the birthday date).

I don't want to store in the database age value for each player - it is obvious.

Should I add to the controller another: model.addAttribute(); with information about age? (it doesnt looks good even for me)

I'm looking for smart solution, comply with the rules of clean code and MVC. I would be glad if you will help me find good solution, thank you.

EDIT: I just create class AgeCalculator:

@Component
@Data
public class AgeCalculator {

    public Integer calculateAge(Player player) {
        return Years.yearsBetween(player.getBirthdayDate(), new LocalDate()).getYears();
    }
}

Modified controller:

@RequestMapping({"player/{playerId}/show"})
    public String getPlayerById(Model model, @PathVariable String playerId) {

        model.addAttribute("player", playerService.getPlayerById(Long.valueOf(playerId)));
        model.addAttribute("ageCalculator", new AgeCalculator());
        return "event/player/showPlayerById";
    }

And in thymeleaf I use:

<p th:text="${ageCalculator.calculateAge(player)}">Here will be a Player age</p>

But I receive an error: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "ageCalculator.calculateAge(player.birthdayDate)"

Whats wrong with my code?

Upvotes: 0

Views: 822

Answers (3)

przemekost
przemekost

Reputation: 91

Ok thanks for all replays. The complete resolution for this problem.

Controller:

@RequestMapping({"player/{playerId}/show"})
    public String getPlayerById(Model model, @PathVariable String playerId) {

        model.addAttribute("player", playerService.getPlayerById(Long.valueOf(playerId)));
        model.addAttribute("ageCalculator", new AgeCalculator());
        return "event/player/showPlayerById";
    }

Age calculator:

@Component
@Data
public class AgeCalculator {

    private LocalDate fromStringToLocalDate(String localDateString) {

        DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy");

        return LocalDate.parse(localDateString, inputFormat);
    }

    public int calculateAge(String birthDate) {
        if (birthDate != null) {
            return Period.between(fromStringToLocalDate(birthDate), LocalDate.now()).getYears();
        } else {
            return 0;
        }
    }
}

Player Domain Class:

@Entity
@Setter
@Getter
@EqualsAndHashCode(exclude = {"events"})
public class Player {
    (...)
    private String birthdayDate;
}

Thymeleaf code:

<p th:text="${ageCalculator.calculateAge(player.birthdayDate)}">Here will be a player age</p>

Upvotes: 0

Den B
Den B

Reputation: 921

You could add just full object or part of it in javascript and work with it like pure value:

<script type="text/javascript" th:inline="javascript">

    /*<![CDATA[*/
    var some_data =/*[[${data}]]*/;
    /*]]>*/

</script>

It just good way to pass parameter from spring controller to frontend.

Upvotes: 1

Metroids
Metroids

Reputation: 20487

My preferred method would be to add a getAge() method to the Player class. Then in the front end, it would look like this:

<span th:text="${player.age}" />

If you don't want to modify the Player class, you could create a helper object with a calculateAge(LocalDate birthday) method, and then add it to the model and call it like this:

Java: model.addAttribute("helper", new BirthdayHelper());

Thymeleaf: <span th:text="${helper.calculateAge(player.birthdayDate)}" />

Upvotes: 1

Related Questions