Home > front end >  How to use spring mvc with thymeleaf to iterate over a list?
How to use spring mvc with thymeleaf to iterate over a list?

Time:06-02

My goal is to cycle through a list of objects, some to be displayed on the screen, others to be passed into a form as an object of which I can define certain aspects and then return to the controller the object and attribute to be modified.

The problem with the following approach is that the object in the list is not passed correctly to the form and thus gives an error because it is trying to make changes to a non-existent object.

If, on the other hand, I try to pass it as an object via ModelAndView it obviously works but does not have all the characteristics of the object I passed via the list.

Controller

@GetMapping("/")
    public ModelAndView home() throws IOException {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("home");

        List<Comics> allComics = cs.getAll();
        
        mv.addObject("comics", allComics);
        return mv;
    }

@PostMapping("/update")
    public ModelAndView update(Comics com, @RequestParam("attr") String attr) throws IOException {
        ModelAndView mv = new ModelAndView();
        
        com.setLastRead(attr);
        
        cs.updateAttributes(com);
        
        mv.setViewName("home");
        List<Comics> allComics = cs.getAll();
        mv.addObject("comics", allComics);
        return mv;
    }

home.html

<html xmlns:th="http://www.thymeleaf.org">
<tr th:each="comic : ${comics}">
                    <td th:text="${comic.title}"></td>
                    <td th:text="${comic.lastChapter}"></td>
                    <td>
                    <a th:href="${comic.lastChapterLink}" target="_blank"
                    role="button" > Link
                    </a>
                    </td>
                        <td></td>
                    <td>
                        <form th:action="@{/update}" th:object="${comic}" method="post">
                            <input type="text" name="attr" id="attr"/>
                            <button type="submit">Sub</button>
                        </form>
                    </td>
</tr>

PS: I cut out the head of the html page because it was full of non-relevant CDNs

How can I integrate Spring MVC with Thymeleaf to achieve the result whereby passing a list of objects can be displayed on the screen and used for other purposes within the html page without throwing errors?

Obviously if you know of more efficient methods to achieve the result I'm listening; I only used this method because I didn't know of any others.

Thank you

Answer to @RafaeldaSilva:

I agree, but that does not solve the problem. Let me explain: the attribute I am going to modify through the form already has its name to allow what you wrote. But the object iterated through:

tr th:each="comic : ${comics}">

cannot be passed directly as input, as it is a value that is taken from a list and exists individually only in the html page. One might think of passing it as hidden input, but in this case the result would be the same (I have tried):

<form th:action="@{/update}" th:object="${comic}" method="post">
                            <input type="hidden" value="${comic}" name="com"/>
                            <input type="text" name="attr" id="attr"/>
                            <button type="submit">Sub</button>
</form>

@PostMapping("/update")
    public ModelAndView update(@RequestParam("com") Comics com, @RequestParam("attr") String attr) throws IOException {
        ModelAndView mv = new ModelAndView();
        
        com.setLastRead(attr);
        
        System.out.println("Comic: "   com);
        
        cs.updateAttributes(com);
        
        mv.setViewName("home");
        List<Comics> allComics = cs.getAll();
        mv.addObject("comics", allComics);
        return mv;
    }

Error: [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'com' for method parameter type Comics is present but converted to null]

CodePudding user response:

try removing the type="hidden" to see what is present in this input, as I understand you are inserting an object by doing value="${comic}", this way the input should not send the value wanted..

change this: <input type="hidden" value="${comic}" name="com"/>

for this: <input type="text" value="${comic}" name="com"/>

so you can see what the form is sending to the controller, I believe it's the object's memory path, and not the data that exists in it.

in the input you must inform the attributes of the object, not the complete object..

  • Related