Search code examples
javaspringspring-bootarraylistthymeleaf

With Thymeleaf how do I display an iteration through an arraylist?


In my controller I have a loop that iterates through an arraylist and displays the attributes belonging to each object in the arraylist and I am wondering what should I put in my thymeleaf code because at the moment it is only displaying the information of the first object in the arraylist.

My Controller class

   @GetMapping("/allSubjects")
public String shoSubjects(@ModelAttribute("subject") @Valid UserRegistrationDto userDto, BindingResult result, Model model) {
    Authentication loggedInUser = SecurityContextHolder.getContext().getAuthentication();
    String email = loggedInUser.getName();   

    User user = userRepository.findByEmailAddress(email);

    ArrayList<String> subjects = new ArrayList<String>();

    for(Subject sub:user.getSubject())
    {
        subjects.add(sub.getSubjectName());
    }
    model.addAttribute("subjects", subjects);


    if(!subjects.isEmpty()) {

    for(int i = 0; i<subjects.size(); i++) {

            String subjectName = (subjects.get(i));
            Subject subject = subjectRepository.findBySubjectName(subjectName);

            String subjectName1 = subject.getSubjectName();
            Double subjectGradeGoal = subject.getSubjectGradeGoal();
            Double caCompletedWorth = subject.getCaCompletedWorth();
            Double subjectResults = subject.getSubjectResults();
            Double maxSubRemMarks = subject.getMaxSubRemMarks();
            Double marksNeededToReachGoal = subject.getMarksNeededToReachGoal();
            Boolean isGoalPossible = subject.getIsGoalPossible();
            Double highestPossibleGrade = subject.getHighestPossibleGrade();

            model.addAttribute("subjectName",subjectName1);
            model.addAttribute("subjectGradeGoal",subjectGradeGoal);
            model.addAttribute("caCompletedWorth",caCompletedWorth);
            model.addAttribute("subjectResults",subjectResults);
            model.addAttribute("maxSubRemMarks",maxSubRemMarks);
            model.addAttribute("marksNeededToReachGoal",marksNeededToReachGoal);
            model.addAttribute("isGoalPossible",isGoalPossible);
            model.addAttribute("highestPossibleGrade",highestPossibleGrade);
            return "allSubjects";

        }


    }

return "allSubjects";

}

My html class

  <>Subject: <h4 th:text="${subjectName}" /> </> 

//I have this for each attribute I have just not added it in for this post.


Solution

  • Assuming your function user.getSubject() returns a collection or an array of Subject objects, do something like the below

    Controller Method

    @GetMapping("/allSubjects")
    public String shoSubjects(@ModelAttribute("subject") @Valid UserRegistrationDto userDto, BindingResult result, Model model) {
        Authentication loggedInUser = SecurityContextHolder.getContext().getAuthentication();
        String email = loggedInUser.getName();   
        User user = userRepository.findByEmailAddress(email);
    
        model.addAttribute("subjects", user.getSubject());
        return "allSubjects";
    }
    

    And in the view

    <div th:each="subject : ${subjects}">
        Subject: <h4 th:text="${subject.subjectName}" />
        Subject Grade Goal: <h4 th:text="${subject.subjectGradeGoal}" />
        <!-- Other Properties -->
    </div>
    

    P.S. It is bad to name your method as user.getSubject() when it returns multiple subjects. It would be better if you modify your method name to user.getSubjects() which implies by its name that multiple objects are returned.